### Bug Summary

File: | epan/proto.c
Warning: | line 13570, 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 -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/2026-01-06-100345-3603-1 -x c /builds/wireshark/wireshark/epan/proto.c

Keyboard shortcuts:

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

Close
Show only relevant lines Show control flow arrows

1 | /* proto.c
2 | * Routines for protocol tree
3 | *
4 | * Wireshark - Network traffic analyzer
5 | * By Gerald Combs <gerald@wireshark.org>
6 | * Copyright 1998 Gerald Combs
7 | *
8 | * SPDX-License-Identifier: GPL-2.0-or-later
9 | */
10 |
11 | #include "config.h"
12 | #define WS_LOG_DOMAIN"Epan" LOG_DOMAIN_EPAN"Epan"
13 | #include "wireshark.h"
14 |
15 | #include <float.h>
16 | #include <errno(*__errno_location ()).h>
17 |
18 | #include <epan/tfs.h>
19 | #include <epan/unit_strings.h>
20 |
21 | #include <wsutil/array.h>
22 | #include <wsutil/bits_ctz.h>
23 | #include <wsutil/bits_count_ones.h>
24 | #include <wsutil/sign_ext.h>
25 | #include <wsutil/utf8_entities.h>
26 | #include <wsutil/json_dumper.h>
27 | #include <wsutil/pint.h>
28 | #include <wsutil/unicode-utils.h>
29 | #include <wsutil/dtoa.h>
30 | #include <wsutil/filesystem.h>
31 | #ifdef HAVE_UNISTD_H1
32 | #include <unistd.h>
33 | #endif
34 |
35 | #include <ftypes/ftypes.h>
36 | #include <ftypes/ftypes-int.h>
37 |
38 | #include <epan/packet.h>
39 | #include "exceptions.h"
40 | #include "ptvcursor.h"
41 | #include "strutil.h"
42 | #include "addr_resolv.h"
43 | #include "address_types.h"
44 | #include "oids.h"
45 | #include "proto.h"
46 | #include "epan_dissect.h"
47 | #include "dfilter/dfilter.h"
48 | #include "tvbuff.h"
49 | #include "charsets.h"
50 | #include "column-info.h"
51 | #include "to_str.h"
52 | #include "osi-utils.h"
53 | #include "expert.h"
54 | #include "show_exception.h"
55 | #include "in_cksum.h"
56 |
57 | #include <wsutil/crash_info.h>
58 | #include <wsutil/epochs.h>
59 |
60 | /* Ptvcursor limits */
61 | #define SUBTREE_ONCE_ALLOCATION_NUMBER8 8
62 | #define SUBTREE_MAX_LEVELS256 256
63 |
64 | typedef struct __subtree_lvl {
65 | int cursor_offset;
66 | proto_item *it;
67 | proto_tree *tree;
68 | } subtree_lvl;
69 |
70 | struct ptvcursor {
71 | wmem_allocator_t *scope;
72 | subtree_lvl *pushed_tree;
73 | uint8_t pushed_tree_index;
74 | uint8_t pushed_tree_max;
75 | proto_tree *tree;
76 | tvbuff_t *tvb;
77 | int offset;
78 | };
79 |
80 | #define cVALS(x)(const value_string*)(x) (const value_string*)(x)
81 |
82 | /** See inlined comments.
83 | @param tree the tree to append this item to
84 | @param free_block a code block to call to free resources if this returns
85 | @return NULL if 'tree' is null */
86 | #define CHECK_FOR_NULL_TREE_AND_FREE(tree, free_block)if (!tree) { free_block; return ((void*)0); } \
87 | if (!tree) { \
88 | free_block; \
89 | return NULL((void*)0); \
90 | }
91 |
92 | /** See inlined comments.
93 | @param tree the tree to append this item to
94 | @return NULL if 'tree' is null */
95 | #define CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); } \
96 | CHECK_FOR_NULL_TREE_AND_FREE(tree, ((void)0))if (!tree) { ((void)0); return ((void*)0); }
97 |
98 | /** See inlined comments.
99 | @param length the length of this item
100 | @param cleanup_block a code block to call to free resources if this returns
101 | @return NULL if 'length' is lower -1 or equal 0 */
102 | #define CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length, cleanup_block)if (length < -1 || length == 0 ) { cleanup_block; return ( (void*)0); } \
103 | if (length < -1 || length == 0 ) { \
104 | cleanup_block; \
105 | return NULL((void*)0); \
106 | }
107 |
108 | /** See inlined comments.
109 | @param length the length of this item
110 | @return NULL if 'length' is lower -1 or equal 0 */
111 | #define CHECK_FOR_ZERO_OR_MINUS_LENGTH(length)if (length < -1 || length == 0 ) { ((void)0); return ((void *)0); } \
112 | CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length, ((void)0))if (length < -1 || length == 0 ) { ((void)0); return ((void *)0); }
113 |
114 | /** See inlined comments.
115 | @param tree the tree to append this item to
116 | @param hfindex field index
117 | @param hfinfo header_field
118 | @param free_block a code block to call to free resources if this returns
119 | @return the header field matching 'hfinfo' */
120 | #define TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, free_block)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned )hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug ) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 120 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 120, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 120, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items ) { free_block; if (wireshark_abort_on_too_many_items) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 120, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { free_block; return proto_tree_add_fake_node(tree, hfinfo ); } } } \
121 | /* If the tree is not visible and this item is not referenced \
122 | we don't have to do much work at all but we should still \
123 | return a node so that referenced field items below this node \
124 | (think proto_item_add_subtree()) will still have somewhere \
125 | to attach to or else filtering will not work (they would be \
126 | ignored since tree would be NULL). \
127 | DON'T try to fake a node where PTREE_FINFO(tree) is visible \
128 | because that means we can change its length or repr, and we \
129 | don't want to do so with calls intended for this faked new \
130 | item, so this item needs a new (hidden) child node. \
131 | We fake FT_PROTOCOL unless some clients have requested us \
132 | not to do so. \
133 | */ \
134 | PTREE_DATA(tree)((tree)->tree_data)->count++; \
135 | PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 135, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 135, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 135, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];; \
136 | if (PTREE_DATA(tree)((tree)->tree_data)->count > prefs.gui_max_tree_items) { \
137 | free_block; \
138 | if (wireshark_abort_on_too_many_items) \
139 | ws_error("Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)", \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 140 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items)
140 | hfinfo->abbrev, prefs.gui_max_tree_items)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 140 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); \
141 | /* Let the exception handler add items to the tree */ \
142 | PTREE_DATA(tree)((tree)->tree_data)->count = 0; \
143 | THROW_MESSAGE(DissectorError, \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data ->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items)))
144 | wmem_strdup_printf(PNODE_POOL(tree), \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data ->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items)))
145 | "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)", \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data ->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items)))
146 | hfinfo->abbrev, prefs.gui_max_tree_items))except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data ->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); \
147 | } \
148 | if (!(PTREE_DATA(tree)((tree)->tree_data)->visible)) { \
149 | if (PROTO_ITEM_IS_HIDDEN(tree)proto_item_is_hidden((tree))) { \
150 | if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) \
151 | && (hfinfo->ref_type != HF_REF_TYPE_PRINT) \
152 | && (hfinfo->type != FT_PROTOCOL || \
153 | PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) { \
154 | free_block; \
155 | /* return fake node with no field info */\
156 | return proto_tree_add_fake_node(tree, hfinfo); \
157 | } \
158 | } \
159 | }
160 |
161 | /** See inlined comments.
162 | @param tree the tree to append this item to
163 | @param hfindex field index
164 | @param hfinfo header_field
165 | @return the header field matching 'hfinfo' */
166 | #define TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned )hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug ) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 166 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 166, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 166, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items ) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 166, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } } \
167 | TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, ((void)0))((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned )hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug ) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 167 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 167, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 167, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items ) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 167, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } }
168 |
169 |
170 | /** See inlined comments.
171 | @param pi the created protocol item we're about to return */
172 | #define TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 172, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; } \
173 | ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 173, __func__, "assertion failed: %s", "pi" ); } while (0); \
174 | if (!PITEM_FINFO(pi)((pi)->finfo)) \
175 | return pi; \
176 | if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
177 | PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
178 | /* If the tree (GUI) or item isn't visible it's pointless for \
179 | * us to generate the protocol item's string representation */ \
180 | return pi; \
181 | }
182 | /* Same as above but returning void */
183 | #define TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data )->visible) && proto_item_is_hidden((pi))) { return ; } \
184 | if (!pi || !PITEM_FINFO(pi)((pi)->finfo)) \
185 | return; \
186 | if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
187 | PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
188 | /* If the tree (GUI) or item isn't visible it's pointless for \
189 | * us to generate the protocol item's string representation */ \
190 | return; \
191 | }
192 | /* Similar to above, but allows a NULL tree */
193 | #define TRY_TO_FAKE_THIS_REPR_NESTED(pi)if ((pi == ((void*)0)) || (((pi)->finfo) == ((void*)0)) || (!(((pi)->tree_data)->visible) && proto_item_is_hidden ((pi)))) { return pi; } \
194 | if ((pi == NULL((void*)0)) || (PITEM_FINFO(pi)((pi)->finfo) == NULL((void*)0)) || (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
195 | PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi)))) { \
196 | /* If the tree (GUI) or item isn't visible it's pointless for \
197 | * us to generate the protocol item's string representation */ \
198 | return pi; \
199 | }
200 |
201 | #ifdef ENABLE_CHECK_FILTER
202 | #define CHECK_HF_VALUE(type, spec, start_values) \
203 | { \
204 | const type *current; \
205 | int n, m; \
206 | current = start_values; \
207 | for (n=0; current; n++, current++) { \
208 | /* Drop out if we reached the end. */ \
209 | if ((current->value == 0) && (current->strptr == NULL((void*)0))) { \
210 | break; \
211 | } \
212 | /* Check value against all previous */ \
213 | for (m=0; m < n; m++) { \
214 | /* There are lots of duplicates with the same string, \
215 | so only report if different... */ \
216 | if ((start_values[m].value == current->value) && \
217 | (strcmp(start_values[m].strptr, current->strptr) != 0)) { \
218 | ws_error("Field '%s' (%s) has a conflicting entry in its" \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221 , __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %" spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo ->abbrev, current->value, m, start_values[m].strptr, n, current->strptr)
219 | " value_string: %" spec " is at indices %u (%s) and %u (%s)", \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221 , __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %" spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo ->abbrev, current->value, m, start_values[m].strptr, n, current->strptr)
220 | hfinfo->name, hfinfo->abbrev, \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221 , __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %" spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo ->abbrev, current->value, m, start_values[m].strptr, n, current->strptr)
221 | current->value, m, start_values[m].strptr, n, current->strptr)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221 , __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %" spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo ->abbrev, current->value, m, start_values[m].strptr, n, current->strptr); \
222 | } \
223 | } \
224 | } \
225 | }
226 | #endif
227 |
228 | /* The longest NUMBER-like field label we have is for BASE_OUI, which
229 | * can have up to 64 bytes for the manufacturer name if resolved plus
230 | * 11 bytes for the "XX:XX:XX ()" part = 75 octets.
231 | */
232 | #define NUMBER_LABEL_LENGTH80 80
233 |
234 | static const char *hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo);
235 | static const char *hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo);
236 | static const char *hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str);
237 | static const char *hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str);
238 | static int hfinfo_bitoffset(const header_field_info *hfinfo);
239 | static int hfinfo_mask_bitwidth(const header_field_info *hfinfo);
240 | static int hfinfo_container_bitwidth(const header_field_info *hfinfo);
241 |
242 | #define label_concat(dst, pos, src)ws_label_strcpy(dst, 240, pos, src, 0) \
243 | ws_label_strcpy(dst, ITEM_LABEL_LENGTH240, pos, src, 0)
244 |
245 | static void mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos);
246 | static void label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos);
247 |
248 | static void fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos);
249 | static void fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos);
250 | static void fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
251 | static void fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
252 | static void fill_label_char(const field_info *fi, char *label_str, size_t *value_pos);
253 | static void fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
254 | static void fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
255 |
256 | static size_t fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size);
257 | static void fill_label_float(const field_info *fi, char *label_str, size_t *value_pos);
258 | static size_t fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size);
259 | static void fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos);
260 |
261 | static const char *hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
262 | static const char *hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
263 | static const char *hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
264 | static const char* hfinfo_char_value_format_display(int display, char buf[7], uint32_t value);
265 | static const char *hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
266 | static const char *hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
267 | static const char *hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
268 | static const char *hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
269 | static const char *hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
270 | static const char *hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
271 | static const char *hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
272 |
273 | static void proto_cleanup_base(void);
274 |
275 | static proto_item *
276 | proto_tree_add_node(proto_tree *tree, field_info *fi);
277 |
278 | static proto_item *
279 | proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo);
280 |
281 | static void
282 | get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start, int *length,
283 | int *item_length, const unsigned encoding);
284 |
285 | static int
286 | get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start,
287 | int length, unsigned item_length, const int encoding);
288 |
289 | static field_info *
290 | new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
291 | const int start, const int item_length);
292 |
293 | static proto_item *
294 | proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
295 | int start, int *length);
296 |
297 | static void
298 | proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap);
299 | static void
300 | proto_tree_set_representation(proto_item *pi, const char *format, va_list ap);
301 |
302 | static void
303 | proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length);
304 | static void
305 | proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length);
306 | static void
307 | proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, int offset, int length);
308 | static void
309 | proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value);
310 | static void
311 | proto_tree_set_time(field_info *fi, const nstime_t *value_ptr);
312 | static void
313 | proto_tree_set_string(field_info *fi, const char* value);
314 | static void
315 | proto_tree_set_ax25(field_info *fi, const uint8_t* value);
316 | static void
317 | proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, int start);
318 | static void
319 | proto_tree_set_vines(field_info *fi, const uint8_t* value);
320 | static void
321 | proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, int start);
322 | static void
323 | proto_tree_set_ether(field_info *fi, const uint8_t* value);
324 | static void
325 | proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, int start);
326 | static void
327 | proto_tree_set_ipxnet(field_info *fi, uint32_t value);
328 | static void
329 | proto_tree_set_ipv4(field_info *fi, ws_in4_addr value);
330 | static void
331 | proto_tree_set_ipv6(field_info *fi, const ws_in6_addr* value);
332 | static void
333 | proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
334 | static void
335 | proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
336 | static void
337 | proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr);
338 | static void
339 | proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding);
340 | static void
341 | proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, int length);
342 | static void
343 | proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
344 | static void
345 | proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, int length);
346 | static void
347 | proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
348 | static void
349 | proto_tree_set_boolean(field_info *fi, uint64_t value);
350 | static void
351 | proto_tree_set_float(field_info *fi, float value);
352 | static void
353 | proto_tree_set_double(field_info *fi, double value);
354 | static void
355 | proto_tree_set_uint(field_info *fi, uint32_t value);
356 | static void
357 | proto_tree_set_int(field_info *fi, int32_t value);
358 | static void
359 | proto_tree_set_uint64(field_info *fi, uint64_t value);
360 | static void
361 | proto_tree_set_int64(field_info *fi, int64_t value);
362 | static void
363 | proto_tree_set_eui64(field_info *fi, const uint64_t value);
364 | static void
365 | proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding);
366 |
367 | /* Handle type length mismatch (now filterable) expert info */
368 | static int proto_type_length_mismatch;
369 | static expert_field ei_type_length_mismatch_error;
370 | static expert_field ei_type_length_mismatch_warn;
371 | static void register_type_length_mismatch(void);
372 |
373 | /* Handle byte array string decoding errors with expert info */
374 | static int proto_byte_array_string_decoding_error;
375 | static expert_field ei_byte_array_string_decoding_failed_error;
376 | static void register_byte_array_string_decodinws_error(void);
377 |
378 | /* Handle date and time string decoding errors with expert info */
379 | static int proto_date_time_string_decoding_error;
380 | static expert_field ei_date_time_string_decoding_failed_error;
381 | static void register_date_time_string_decodinws_error(void);
382 |
383 | /* Handle string errors expert info */
384 | static int proto_string_errors;
385 | static expert_field ei_string_trailing_characters;
386 | static void register_string_errors(void);
387 |
388 | static int proto_register_field_init(header_field_info *hfinfo, const int parent);
389 |
390 | /* special-case header field used within proto.c */
391 | static header_field_info hfi_text_only =
392 | { "Text item", "text", FT_NONE, BASE_NONE, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) };
393 | int hf_text_only;
394 |
395 | /* Structure for information about a protocol */
396 | struct _protocol {
397 | const char *name; /* long description */
398 | const char *short_name; /* short description */
399 | const char *filter_name; /* name of this protocol in filters */
400 | GPtrArray *fields; /* fields for this protocol */
401 | int proto_id; /* field ID for this protocol */
402 | bool_Bool is_enabled; /* true if protocol is enabled */
403 | bool_Bool enabled_by_default; /* true if protocol is enabled by default */
404 | bool_Bool can_toggle; /* true if is_enabled can be changed */
405 | int parent_proto_id; /* Used to identify "pino"s (Protocol In Name Only).
406 | For dissectors that need a protocol name so they
407 | can be added to a dissector table, but use the
408 | parent_proto_id for things like enable/disable */
409 | GList *heur_list; /* Heuristic dissectors associated with this protocol */
410 | };
411 |
412 | /* List of all protocols */
413 | static GList *protocols;
414 |
415 | /* Structure stored for deregistered g_slice */
416 | struct g_slice_data {
417 | size_t block_size;
418 | void *mem_block;
419 | };
420 |
421 | /* Deregistered fields */
422 | static GPtrArray *deregistered_fields;
423 | static GPtrArray *deregistered_data;
424 | static GPtrArray *deregistered_slice;
425 |
426 | /* indexed by prefix, contains initializers */
427 | static GHashTable* prefixes;
428 |
429 | /* Contains information about a field when a dissector calls
430 | * proto_tree_add_item. */
431 | #define FIELD_INFO_NEW(pool, fi)fi = ((field_info*)wmem_alloc((pool), sizeof(field_info))) fi = wmem_new(pool, field_info)((field_info*)wmem_alloc((pool), sizeof(field_info)))
432 | #define FIELD_INFO_FREE(pool, fi)wmem_free(pool, fi) wmem_free(pool, fi)
433 |
434 | /* Contains the space for proto_nodes. */
435 | #define PROTO_NODE_INIT(node)node->first_child = ((void*)0); node->last_child = ((void *)0); node->next = ((void*)0); \
436 | node->first_child = NULL((void*)0); \
437 | node->last_child = NULL((void*)0); \
438 | node->next = NULL((void*)0);
439 |
440 | #define PROTO_NODE_FREE(pool, node)wmem_free(pool, node) \
441 | wmem_free(pool, node)
442 |
443 | /* String space for protocol and field items for the GUI */
444 | #define ITEM_LABEL_NEW(pool, il)il = ((item_label_t*)wmem_alloc((pool), sizeof(item_label_t)) ); il->value_pos = 0; il->value_len = 0; \
445 | il = wmem_new(pool, item_label_t)((item_label_t*)wmem_alloc((pool), sizeof(item_label_t))); \
446 | il->value_pos = 0; \
447 | il->value_len = 0;
448 | #define ITEM_LABEL_FREE(pool, il)wmem_free(pool, il); \
449 | wmem_free(pool, il);
450 |
451 | #define PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 451, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 451, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 451, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex]; \
452 | if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug) \
453 | ws_error("Unregistered hf! index=%d", hfindex)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 453 , __func__, "Unregistered hf! index=%d", hfindex); \
454 | DISSECTOR_ASSERT_HINT(hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len, "Unregistered hf!")((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo .len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 454, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))); \
455 | DISSECTOR_ASSERT_HINT(gpa_hfinfo.hfi[hfindex] != NULL, "Unregistered hf!")((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : ( proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 455, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))); \
456 | hfinfo = gpa_hfinfo.hfi[hfindex];
457 |
458 | #define PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000) (300000+PRE_ALLOC_EXPERT_FIELDS_MEM5000)
459 |
460 | /* List which stores protocols and fields that have been registered */
461 | typedef struct _gpa_hfinfo_t {
462 | uint32_t len;
463 | uint32_t allocated_len;
464 | header_field_info **hfi;
465 | } gpa_hfinfo_t;
466 |
467 | static gpa_hfinfo_t gpa_hfinfo;
468 |
469 | /* Hash table of abbreviations and IDs */
470 | static wmem_map_t *gpa_name_map;
471 | static header_field_info *same_name_hfinfo;
472 |
473 | /* Hash table protocol aliases. const char * -> const char * */
474 | static GHashTable *gpa_protocol_aliases;
475 |
476 | /*
477 | * We're called repeatedly with the same field name when sorting a column.
478 | * Cache our last gpa_name_map hit for faster lookups.
479 | */
480 | static char *last_field_name;
481 | static header_field_info *last_hfinfo;
482 |
483 | /* Points to the first element of an array of bits, indexed by
484 | a subtree item type; that array element is true if subtrees of
485 | an item of that type are to be expanded. */
486 | static uint32_t *tree_is_expanded;
487 |
488 | /* Number of elements in that array. The entry with index 0 is not used. */
489 | int num_tree_types = 1;
490 |
491 | /* Name hashtables for fast detection of duplicate names */
492 | static GHashTable* proto_names;
493 | static GHashTable* proto_short_names;
494 | static GHashTable* proto_filter_names;
495 |
496 | static const char * const reserved_filter_names[] = {
497 | /* Display filter keywords. */
498 | "eq",
499 | "ne",
500 | "all_eq",
501 | "any_eq",
502 | "all_ne",
503 | "any_ne",
504 | "gt",
505 | "ge",
506 | "lt",
507 | "le",
508 | "bitand",
509 | "bitwise_and",
510 | "contains",
511 | "matches",
512 | "not",
513 | "and",
514 | "or",
515 | "xor",
516 | "in",
517 | "any",
518 | "all",
519 | "true",
520 | "false",
521 | "nan",
522 | "inf",
523 | "infinity",
524 | NULL((void*)0)
525 | };
526 |
527 | static GHashTable *proto_reserved_filter_names;
528 | static GQueue* saved_dir_queue;
529 |
530 | static int
531 | proto_compare_name(const void *p1_arg, const void *p2_arg)
532 | {
533 | const protocol_t *p1 = (const protocol_t *)p1_arg;
534 | const protocol_t *p2 = (const protocol_t *)p2_arg;
535 |
536 | return g_ascii_strcasecmp(p1->short_name, p2->short_name);
537 | }
538 |
539 | static GSList *dissector_plugins;
540 |
541 | #ifdef HAVE_PLUGINS1
542 | void
543 | proto_register_plugin(const proto_plugin *plug)
544 | {
545 | dissector_plugins = g_slist_prepend(dissector_plugins, (proto_plugin *)plug);
546 | }
547 | #else /* HAVE_PLUGINS */
548 | void
549 | proto_register_plugin(const proto_plugin *plug _U___attribute__((unused)))
550 | {
551 | ws_warning("proto_register_plugin: built without support for binary plugins")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 551, __func__, "proto_register_plugin: built without support for binary plugins" ); } } while (0);
552 | }
553 | #endif /* HAVE_PLUGINS */
554 |
555 | static void
556 | call_plugin_register_protoinfo(void *data, void *user_data _U___attribute__((unused)))
557 | {
558 | proto_plugin *plug = (proto_plugin *)data;
559 |
560 | if (plug->register_protoinfo) {
561 | plug->register_protoinfo();
562 | }
563 | }
564 |
565 | static void
566 | call_plugin_register_handoff(void *data, void *user_data _U___attribute__((unused)))
567 | {
568 | proto_plugin *plug = (proto_plugin *)data;
569 |
570 | if (plug->register_handoff) {
571 | plug->register_handoff();
572 | }
573 | }
574 |
575 | void proto_pre_init(void)
576 | {
577 | saved_dir_queue = g_queue_new();
578 |
579 | proto_names = g_hash_table_new(wmem_str_hash, g_str_equal);
580 | proto_short_names = g_hash_table_new(wmem_str_hash, g_str_equal);
581 | proto_filter_names = g_hash_table_new(wmem_str_hash, g_str_equal);
582 |
583 | proto_reserved_filter_names = g_hash_table_new(wmem_str_hash, g_str_equal);
584 | for (const char* const * ptr = reserved_filter_names; *ptr != NULL((void*)0); ptr++) {
585 | /* GHashTable has no key destructor so the cast is safe. */
586 | g_hash_table_add(proto_reserved_filter_names, *(char**)ptr);
587 | }
588 |
589 | gpa_hfinfo.len = 0;
590 | gpa_hfinfo.allocated_len = 0;
591 | gpa_hfinfo.hfi = NULL((void*)0);
592 | gpa_name_map = wmem_map_new(wmem_epan_scope(), wmem_str_hash, g_str_equal);
593 | wmem_map_reserve(gpa_name_map, PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
594 | gpa_protocol_aliases = g_hash_table_new(wmem_str_hash, g_str_equal);
595 | deregistered_fields = g_ptr_array_new();
596 | deregistered_data = g_ptr_array_new();
597 | deregistered_slice = g_ptr_array_new();
598 | }
599 |
600 | /* initialize data structures and register protocols and fields */
601 | void
602 | proto_init(GSList *register_all_plugin_protocols_list,
603 | GSList *register_all_plugin_handoffs_list,
604 | register_entity_func register_func, register_entity_func handoff_func,
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 | if (register_func != NULL((void*)0))
633 | register_func(cb, client_data);
634 |
635 | /* Now call the registration routines for all epan plugins. */
636 | for (GSList *l = register_all_plugin_protocols_list; l != NULL((void*)0); l = l->next) {
637 | ((void (*)(register_cb, void *))l->data)(cb, client_data);
638 | }
639 |
640 | /* Now call the registration routines for all dissector plugins. */
641 | if (cb)
642 | (*cb)(RA_PLUGIN_REGISTER, NULL((void*)0), client_data);
643 | g_slist_foreach(dissector_plugins, call_plugin_register_protoinfo, NULL((void*)0));
644 |
645 | /* Now call the "handoff registration" routines of all built-in
646 | dissectors; those routines register the dissector in other
647 | dissectors' handoff tables, and fetch any dissector handles
648 | they need. */
649 | if (handoff_func != NULL((void*)0))
650 | handoff_func(cb, client_data);
651 |
652 | /* Now do the same with epan plugins. */
653 | for (GSList *l = register_all_plugin_handoffs_list; l != NULL((void*)0); l = l->next) {
654 | ((void (*)(register_cb, void *))l->data)(cb, client_data);
655 | }
656 |
657 | /* Now do the same with dissector plugins. */
658 | if (cb)
659 | (*cb)(RA_PLUGIN_HANDOFF, NULL((void*)0), client_data);
660 | g_slist_foreach(dissector_plugins, call_plugin_register_handoff, NULL((void*)0));
661 |
662 | /* sort the protocols by protocol name */
663 | protocols = g_list_sort(protocols, proto_compare_name);
664 |
665 | /* sort the dissector handles in dissector tables (for -G reports
666 | * and -d error messages. The GUI sorts the handles itself.) */
667 | packet_all_tables_sort_handles();
668 |
669 | /* We've assigned all the subtree type values; allocate the array
670 | for them, and zero it out. */
671 | 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 )));
672 | }
673 |
674 | static void
675 | proto_cleanup_base(void)
676 | {
677 | protocol_t *protocol;
678 | header_field_info *hfinfo;
679 |
680 | /* Free the abbrev/ID hash table */
681 | if (gpa_name_map) {
682 | // XXX - We don't have a wmem_map_destroy, but
683 | // it does get cleaned up when epan scope is
684 | // destroyed
685 | //g_hash_table_destroy(gpa_name_map);
686 | gpa_name_map = NULL((void*)0);
687 | }
688 | if (gpa_protocol_aliases) {
689 | g_hash_table_destroy(gpa_protocol_aliases);
690 | gpa_protocol_aliases = NULL((void*)0);
691 | }
692 | g_free(last_field_name);
693 | last_field_name = NULL((void*)0);
694 |
695 | while (protocols) {
696 | protocol = (protocol_t *)protocols->data;
697 | 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", 697 , __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", 697, "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", 697, "gpa_hfinfo.hfi[protocol->proto_id] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[protocol-> proto_id];;
698 | 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", 698, "protocol->proto_id == hfinfo->id" ))));
699 |
700 | 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);
701 | if (protocol->parent_proto_id != -1) {
702 | // pino protocol
703 | DISSECTOR_ASSERT(protocol->fields == NULL)((void) ((protocol->fields == ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 703, "protocol->fields == ((void*)0)" )))); //helpers should not have any registered fields
704 | 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" , 704, "protocol->heur_list == ((void*)0)")))); //helpers should not have a heuristic list
705 | } else {
706 | if (protocol->fields) {
707 | g_ptr_array_free(protocol->fields, true1);
708 | }
709 | g_list_free(protocol->heur_list);
710 | }
711 | protocols = g_list_remove(protocols, protocol);
712 | g_free(protocol);
713 | }
714 |
715 | if (proto_names) {
716 | g_hash_table_destroy(proto_names);
717 | proto_names = NULL((void*)0);
718 | }
719 |
720 | if (proto_short_names) {
721 | g_hash_table_destroy(proto_short_names);
722 | proto_short_names = NULL((void*)0);
723 | }
724 |
725 | if (proto_filter_names) {
726 | g_hash_table_destroy(proto_filter_names);
727 | proto_filter_names = NULL((void*)0);
728 | }
729 |
730 | if (proto_reserved_filter_names) {
731 | g_hash_table_destroy(proto_reserved_filter_names);
732 | proto_reserved_filter_names = NULL((void*)0);
733 | }
734 |
735 | if (gpa_hfinfo.allocated_len) {
736 | gpa_hfinfo.len = 0;
737 | gpa_hfinfo.allocated_len = 0;
738 | g_free(gpa_hfinfo.hfi);
739 | gpa_hfinfo.hfi = NULL((void*)0);
740 | }
741 |
742 | if (deregistered_fields) {
743 | g_ptr_array_free(deregistered_fields, true1);
744 | deregistered_fields = NULL((void*)0);
745 | }
746 |
747 | if (deregistered_data) {
748 | g_ptr_array_free(deregistered_data, true1);
749 | deregistered_data = NULL((void*)0);
750 | }
751 |
752 | if (deregistered_slice) {
753 | g_ptr_array_free(deregistered_slice, true1);
754 | deregistered_slice = NULL((void*)0);
755 | }
756 |
757 | g_free(tree_is_expanded);
758 | tree_is_expanded = NULL((void*)0);
759 |
760 | if (prefixes)
761 | g_hash_table_destroy(prefixes);
762 |
763 | if (saved_dir_queue != NULL((void*)0)) {
764 | g_queue_clear_full(saved_dir_queue, g_free);
765 | g_queue_free(saved_dir_queue);
766 | saved_dir_queue = NULL((void*)0);
767 | }
768 | }
769 |
770 | void
771 | proto_cleanup(void)
772 | {
773 | proto_free_deregistered_fields();
774 | proto_cleanup_base();
775 |
776 | g_slist_free(dissector_plugins);
777 | dissector_plugins = NULL((void*)0);
778 | }
779 |
780 | static bool_Bool
781 | ws_pushd(const char* dir)
782 | {
783 | //Save the current working directory
784 | const char* save_wd = get_current_working_dir();
785 | if (save_wd != NULL((void*)0))
786 | g_queue_push_head(saved_dir_queue, g_strdup(save_wd)g_strdup_inline (save_wd));
787 |
788 | //Change to the new one
789 | #ifdef _WIN32
790 | SetCurrentDirectory(utf_8to16(dir));
791 | return true1;
792 | #else
793 | return (chdir(dir) == 0);
794 | #endif
795 | }
796 |
797 | static bool_Bool
798 | ws_popd(void)
799 | {
800 | int ret = 0;
801 | char* saved_wd = g_queue_pop_head(saved_dir_queue);
802 | if (saved_wd == NULL((void*)0))
803 | return false0;
804 |
805 | //Restore the previous one
806 | #ifdef _WIN32
807 | SetCurrentDirectory(utf_8to16(saved_wd));
808 | #else
809 | ret = chdir(saved_wd);
810 | #endif
811 | g_free(saved_wd);
812 | return (ret == 0);
813 | }
814 |
815 | void
816 | proto_execute_in_directory(const char* dir, proto_execute_in_directory_func func, void* param)
817 | {
818 | if (ws_pushd(dir))
819 | {
820 | func(param);
821 | ws_popd();
822 | }
823 | }
824 |
825 | static bool_Bool
826 | // NOLINTNEXTLINE(misc-no-recursion)
827 | proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
828 | void *data)
829 | {
830 | proto_node *pnode = tree;
831 | proto_node *child;
832 | proto_node *current;
833 |
834 | if (func(pnode, data))
835 | return true1;
836 |
837 | child = pnode->first_child;
838 | while (child != NULL((void*)0)) {
839 | /*
840 | * The routine we call might modify the child, e.g. by
841 | * freeing it, so we get the child's successor before
842 | * calling that routine.
843 | */
844 | current = child;
845 | child = current->next;
846 | // We recurse here, but we're limited by prefs.gui_max_tree_depth
847 | if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
848 | return true1;
849 | }
850 |
851 | return false0;
852 | }
853 |
854 | void
855 | proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
856 | void *data)
857 | {
858 | proto_node *node = tree;
859 | proto_node *current;
860 |
861 | if (!node)
862 | return;
863 |
864 | node = node->first_child;
865 | while (node != NULL((void*)0)) {
866 | current = node;
867 | node = current->next;
868 | func((proto_tree *)current, data);
869 | }
870 | }
871 |
872 | static void
873 | free_GPtrArray_value(void *key, void *value, void *user_data _U___attribute__((unused)))
874 | {
875 | GPtrArray *ptrs = (GPtrArray *)value;
876 | int hfid = GPOINTER_TO_UINT(key)((guint) (gulong) (key));
877 | header_field_info *hfinfo;
878 |
879 | 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", 879, __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", 879, "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", 879, "gpa_hfinfo.hfi[hfid] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[hfid];;
880 | if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
881 | /* when a field is referenced by a filter this also
882 | affects the refcount for the parent protocol so we need
883 | to adjust the refcount for the parent as well
884 | */
885 | if (hfinfo->parent != -1) {
886 | header_field_info *parent_hfinfo;
887 | 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", 887 , __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", 887, "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", 887, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)" , "Unregistered hf!")))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo ->parent];;
888 | parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
889 | }
890 | hfinfo->ref_type = HF_REF_TYPE_NONE;
891 | }
892 |
893 | g_ptr_array_free(ptrs, true1);
894 | }
895 |
896 | static void
897 | proto_tree_free_node(proto_node *node, void *data _U___attribute__((unused)))
898 | {
899 | field_info *finfo = PNODE_FINFO(node)((node)->finfo);
900 |
901 | proto_tree_children_foreach(node, proto_tree_free_node, NULL((void*)0));
902 |
903 | if (finfo) {
904 | fvalue_free(finfo->value);
905 | finfo->value = NULL((void*)0);
906 | }
907 | }
908 |
909 | void
910 | proto_tree_reset(proto_tree *tree)
911 | {
912 | tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
913 |
914 | proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
915 |
916 | /* free tree data */
917 | if (tree_data->interesting_hfids) {
918 | /* Free all the GPtrArray's in the interesting_hfids hash. */
919 | g_hash_table_foreach(tree_data->interesting_hfids,
920 | free_GPtrArray_value, NULL((void*)0));
921 |
922 | /* And then remove all values. */
923 | g_hash_table_remove_all(tree_data->interesting_hfids);
924 | }
925 |
926 | /* Reset track of the number of children */
927 | tree_data->count = 0;
928 |
929 | /* Reset our loop checks */
930 | tree_data->idle_count_ds_tvb = NULL((void*)0);
931 | tree_data->max_start = 0;
932 | tree_data->start_idle_count = 0;
933 |
934 | PROTO_NODE_INIT(tree)tree->first_child = ((void*)0); tree->last_child = ((void *)0); tree->next = ((void*)0);;
935 | }
936 |
937 | /* frees the resources that the dissection a proto_tree uses */
938 | void
939 | proto_tree_free(proto_tree *tree)
940 | {
941 | tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
942 |
943 | proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
944 |
945 | /* free tree data */
946 | if (tree_data->interesting_hfids) {
947 | /* Free all the GPtrArray's in the interesting_hfids hash. */
948 | g_hash_table_foreach(tree_data->interesting_hfids,
949 | free_GPtrArray_value, NULL((void*)0));
950 |
951 | /* And then destroy the hash. */
952 | g_hash_table_destroy(tree_data->interesting_hfids);
953 | }
954 |
955 | 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);
956 |
957 | g_slice_free(proto_tree, tree)do { if (1) g_slice_free1 (sizeof (proto_tree), (tree)); else (void) ((proto_tree*) 0 == (tree)); } while (0);
958 | }
959 |
960 | /* Is the parsing being done for a visible proto_tree or an invisible one?
961 | * By setting this correctly, the proto_tree creation is sped up by not
962 | * having to call vsnprintf and copy strings around.
963 | */
964 | bool_Bool
965 | proto_tree_set_visible(proto_tree *tree, bool_Bool visible)
966 | {
967 | bool_Bool old_visible = PTREE_DATA(tree)((tree)->tree_data)->visible;
968 |
969 | PTREE_DATA(tree)((tree)->tree_data)->visible = visible;
970 |
971 | return old_visible;
972 | }
973 |
974 | void
975 | proto_tree_set_fake_protocols(proto_tree *tree, bool_Bool fake_protocols)
976 | {
977 | if (tree)
978 | PTREE_DATA(tree)((tree)->tree_data)->fake_protocols = fake_protocols;
979 | }
980 |
981 | /* Assume dissector set only its protocol fields.
982 | This function is called by dissectors and allows the speeding up of filtering
983 | in wireshark; if this function returns false it is safe to reset tree to NULL
984 | and thus skip calling most of the expensive proto_tree_add_...()
985 | functions.
986 | If the tree is visible we implicitly assume the field is referenced.
987 | */
988 | bool_Bool
989 | proto_field_is_referenced(proto_tree *tree, int proto_id)
990 | {
991 | register header_field_info *hfinfo;
992 |
993 |
994 | if (!tree)
995 | return false0;
996 |
997 | if (PTREE_DATA(tree)((tree)->tree_data)->visible)
998 | return true1;
999 |
1000 | 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", 1000, __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", 1000, "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", 1000, "gpa_hfinfo.hfi[proto_id] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];;
1001 | if (hfinfo->ref_type != HF_REF_TYPE_NONE)
1002 | return true1;
1003 |
1004 | if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)
1005 | return true1;
1006 |
1007 | return false0;
1008 | }
1009 |
1010 |
1011 | /* Finds a record in the hfinfo array by id. */
1012 | header_field_info *
1013 | proto_registrar_get_nth(unsigned hfindex)
1014 | {
1015 | register header_field_info *hfinfo;
1016 |
1017 | 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", 1017, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 1017, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 1017, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
1018 | return hfinfo;
1019 | }
1020 |
1021 |
1022 | /* Prefix initialization
1023 | * this allows for a dissector to register a display filter name prefix
1024 | * so that it can delay the initialization of the hf array as long as
1025 | * possible.
1026 | */
1027 |
1028 | /* compute a hash for the part before the dot of a display filter */
1029 | static unsigned
1030 | prefix_hash (const void *key) {
1031 | /* end the string at the dot and compute its hash */
1032 | char* copy = g_strdup((const char *)key)g_strdup_inline ((const char *)key);
1033 | char* c = copy;
1034 | unsigned tmp;
1035 |
1036 | for (; *c; c++) {
1037 | if (*c == '.') {
1038 | *c = 0;
1039 | break;
1040 | }
1041 | }
1042 |
1043 | tmp = wmem_str_hash(copy);
1044 | g_free(copy);
1045 | return tmp;
1046 | }
1047 |
1048 | /* are both strings equal up to the end or the dot? */
1049 | static gboolean
1050 | prefix_equal (const void *ap, const void *bp) {
1051 | const char* a = (const char *)ap;
1052 | const char* b = (const char *)bp;
1053 |
1054 | do {
1055 | char ac = *a++;
1056 | char bc = *b++;
1057 |
1058 | if ( (ac == '.' || ac == '\0') && (bc == '.' || bc == '\0') ) return TRUE(!(0));
1059 |
1060 | if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE(0);
1061 | if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE(0);
1062 |
1063 | if (ac != bc) return FALSE(0);
1064 | } while (1);
1065 |
1066 | return FALSE(0);
1067 | }
1068 |
1069 | /* Register a new prefix for "delayed" initialization of field arrays */
1070 | void
1071 | proto_register_prefix(const char *prefix, prefix_initializer_t pi ) {
1072 | if (! prefixes ) {
1073 | prefixes = g_hash_table_new(prefix_hash, prefix_equal);
1074 | }
1075 |
1076 | g_hash_table_insert(prefixes, (void *)prefix, (void *)pi);
1077 | }
1078 |
1079 | /* helper to call all prefix initializers */
1080 | static gboolean
1081 | initialize_prefix(void *k, void *v, void *u _U___attribute__((unused))) {
1082 | ((prefix_initializer_t)v)((const char *)k);
1083 | return TRUE(!(0));
1084 | }
1085 |
1086 | /** Initialize every remaining uninitialized prefix. */
1087 | void
1088 | proto_initialize_all_prefixes(void) {
1089 | g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL((void*)0));
1090 | }
1091 |
1092 | /* Finds a record in the hfinfo array by name.
1093 | * If it fails to find it in the already registered fields,
1094 | * it tries to find and call an initializer in the prefixes
1095 | * table and if so it looks again.
1096 | */
1097 |
1098 | header_field_info *
1099 | proto_registrar_get_byname(const char *field_name)
1100 | {
1101 | header_field_info *hfinfo;
1102 | prefix_initializer_t pi;
1103 |
1104 | if (!field_name)
1105 | return NULL((void*)0);
1106 |
1107 | if (g_strcmp0(field_name, last_field_name) == 0) {
1108 | return last_hfinfo;
1109 | }
1110 |
1111 | hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1112 |
1113 | if (hfinfo) {
1114 | g_free(last_field_name);
1115 | last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1116 | last_hfinfo = hfinfo;
1117 | return hfinfo;
1118 | }
1119 |
1120 | if (!prefixes)
1121 | return NULL((void*)0);
1122 |
1123 | if ((pi = (prefix_initializer_t)g_hash_table_lookup(prefixes, field_name) ) != NULL((void*)0)) {
1124 | pi(field_name);
1125 | g_hash_table_remove(prefixes, field_name);
1126 | } else {
1127 | return NULL((void*)0);
1128 | }
1129 |
1130 | hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1131 |
1132 | if (hfinfo) {
1133 | g_free(last_field_name);
1134 | last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1135 | last_hfinfo = hfinfo;
1136 | }
1137 | return hfinfo;
1138 | }
1139 |
1140 | header_field_info*
1141 | proto_registrar_get_byalias(const char *alias_name)
1142 | {
1143 | if (!alias_name) {
1144 | return NULL((void*)0);
1145 | }
1146 |
1147 | /* Find our aliased protocol. */
1148 | char *an_copy = g_strdup(alias_name)g_strdup_inline (alias_name);
1149 | char *dot = strchr(an_copy, '.');
1150 | if (dot) {
1151 | *dot = '\0';
1152 | }
1153 | const char *proto_pfx = (const char *) g_hash_table_lookup(gpa_protocol_aliases, an_copy);
1154 | if (!proto_pfx) {
1155 | g_free(an_copy);
1156 | return NULL((void*)0);
1157 | }
1158 |
1159 | /* Construct our aliased field and look it up. */
1160 | GString *filter_name = g_string_new(proto_pfx);
1161 | if (dot) {
1162 | g_string_append_printf(filter_name, ".%s", dot+1);
1163 | }
1164 | header_field_info *hfinfo = proto_registrar_get_byname(filter_name->str);
1165 | g_free(an_copy);
1166 | 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)))));
1167 |
1168 | return hfinfo;
1169 | }
1170 |
1171 | int
1172 | proto_registrar_get_id_byname(const char *field_name)
1173 | {
1174 | header_field_info *hfinfo;
1175 |
1176 | hfinfo = proto_registrar_get_byname(field_name);
1177 |
1178 | if (!hfinfo)
1179 | return -1;
1180 |
1181 | return hfinfo->id;
1182 | }
1183 |
1184 | static int
1185 | label_strcat_flags(const header_field_info *hfinfo)
1186 | {
1187 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) & BASE_STR_WSP)
1188 | return FORMAT_LABEL_REPLACE_SPACE(0x1 << 0);
1189 |
1190 | return 0;
1191 | }
1192 |
1193 | static char *
1194 | format_bytes_hfinfo_maxlen(wmem_allocator_t *scope, const header_field_info *hfinfo,
1195 | const uint8_t *bytes, unsigned length, size_t max_str_len)
1196 | {
1197 | char *str = NULL((void*)0);
1198 | const uint8_t *p;
1199 | bool_Bool is_printable;
1200 |
1201 | if (bytes) {
1202 | if (hfinfo->display & BASE_SHOW_UTF_8_PRINTABLE0x00020000) {
1203 | /*
1204 | * If all bytes are valid and printable UTF-8, show the
1205 | * bytes as a string - in quotes to indicate that it's
1206 | * a string.
1207 | */
1208 | if (isprint_utf8_string((const char*)bytes, length)) {
1209 | str = wmem_strdup_printf(scope, "\"%.*s\"",
1210 | (int)length, bytes);
1211 | return str;
1212 | }
1213 | } else if (hfinfo->display & BASE_SHOW_ASCII_PRINTABLE0x00010000) {
1214 | /*
1215 | * Check whether all bytes are printable.
1216 | */
1217 | is_printable = true1;
1218 | for (p = bytes; p < bytes+length; p++) {
1219 | if (!g_ascii_isprint(*p)((g_ascii_table[(guchar) (*p)] & G_ASCII_PRINT) != 0)) {
1220 | /* Not printable. */
1221 | is_printable = false0;
1222 | break;
1223 | }
1224 | }
1225 |
1226 | /*
1227 | * If all bytes are printable ASCII, show the bytes
1228 | * as a string - in quotes to indicate that it's
1229 | * a string.
1230 | */
1231 | if (is_printable) {
1232 | str = wmem_strdup_printf(scope, "\"%.*s\"",
1233 | (int)length, bytes);
1234 | return str;
1235 | }
1236 | }
1237 |
1238 | /*
1239 | * Either it's not printable ASCII, or we don't care whether
1240 | * it's printable ASCII; show it as hex bytes.
1241 | */
1242 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
1243 | case SEP_DOT:
1244 | str = bytes_to_str_punct_maxlen(scope, bytes, length, '.', max_str_len/3);
1245 | break;
1246 | case SEP_DASH:
1247 | str = bytes_to_str_punct_maxlen(scope, bytes, length, '-', max_str_len/3);
1248 | break;
1249 | case SEP_COLON:
1250 | str = bytes_to_str_punct_maxlen(scope, bytes, length, ':', max_str_len/3);
1251 | break;
1252 | case SEP_SPACE:
1253 | str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1254 | break;
1255 | case BASE_NONE:
1256 | default:
1257 | if (prefs.display_byte_fields_with_spaces) {
1258 | str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1259 | } else {
1260 | str = bytes_to_str_maxlen(scope, bytes, length, max_str_len/2);
1261 | }
1262 | break;
1263 | }
1264 | }
1265 | else {
1266 | if (hfinfo->display & BASE_ALLOW_ZERO0x00000800) {
1267 | str = wmem_strdup(scope, "<none>");
1268 | } else {
1269 | str = wmem_strdup(scope, "<MISSING>");
1270 | }
1271 | }
1272 | return str;
1273 | }
1274 |
1275 | static char *
1276 | format_bytes_hfinfo(wmem_allocator_t *scope, const header_field_info *hfinfo,
1277 | const uint8_t *bytes, unsigned length)
1278 | {
1279 | return format_bytes_hfinfo_maxlen(scope, hfinfo, bytes, length, ITEM_LABEL_LENGTH240);
1280 | }
1281 |
1282 | static void
1283 | ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
1284 | {
1285 | subtree_lvl *pushed_tree;
1286 |
1287 | 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" , 1287, "ptvc->pushed_tree_max <= 256-8"))));
1288 | ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER8;
1289 |
1290 | pushed_tree = (subtree_lvl *)wmem_realloc(ptvc->scope, (void *)ptvc->pushed_tree, sizeof(subtree_lvl) * ptvc->pushed_tree_max);
1291 | DISSECTOR_ASSERT(pushed_tree != NULL)((void) ((pushed_tree != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1291, "pushed_tree != ((void*)0)" ))));
1292 | ptvc->pushed_tree = pushed_tree;
1293 | }
1294 |
1295 | static void
1296 | ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
1297 | {
1298 | ptvc->pushed_tree = NULL((void*)0);
1299 | ptvc->pushed_tree_max = 0;
1300 | 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", 1300, "ptvc->pushed_tree_index == 0" ))));
1301 | ptvc->pushed_tree_index = 0;
1302 | }
1303 |
1304 | /* Allocates an initializes a ptvcursor_t with 3 variables:
1305 | * proto_tree, tvbuff, and offset. */
1306 | ptvcursor_t *
1307 | ptvcursor_new(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb, int offset)
1308 | {
1309 | ptvcursor_t *ptvc;
1310 |
1311 | ptvc = wmem_new(scope, ptvcursor_t)((ptvcursor_t*)wmem_alloc((scope), sizeof(ptvcursor_t)));
1312 | ptvc->scope = scope;
1313 | ptvc->tree = tree;
1314 | ptvc->tvb = tvb;
1315 | ptvc->offset = offset;
1316 | ptvc->pushed_tree = NULL((void*)0);
1317 | ptvc->pushed_tree_max = 0;
1318 | ptvc->pushed_tree_index = 0;
1319 | return ptvc;
1320 | }
1321 |
1322 |
1323 | /* Frees memory for ptvcursor_t, but nothing deeper than that. */
1324 | void
1325 | ptvcursor_free(ptvcursor_t *ptvc)
1326 | {
1327 | ptvcursor_free_subtree_levels(ptvc);
1328 | /*g_free(ptvc);*/
1329 | }
1330 |
1331 | /* Returns tvbuff. */
1332 | tvbuff_t *
1333 | ptvcursor_tvbuff(ptvcursor_t *ptvc)
1334 | {
1335 | return ptvc->tvb;
1336 | }
1337 |
1338 | /* Returns current offset. */
1339 | int
1340 | ptvcursor_current_offset(ptvcursor_t *ptvc)
1341 | {
1342 | return ptvc->offset;
1343 | }
1344 |
1345 | proto_tree *
1346 | ptvcursor_tree(ptvcursor_t *ptvc)
1347 | {
1348 | if (!ptvc)
1349 | return NULL((void*)0);
1350 |
1351 | return ptvc->tree;
1352 | }
1353 |
1354 | void
1355 | ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
1356 | {
1357 | ptvc->tree = tree;
1358 | }
1359 |
1360 | /* creates a subtree, sets it as the working tree and pushes the old working tree */
1361 | proto_tree *
1362 | ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1363 | {
1364 | subtree_lvl *subtree;
1365 | if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
1366 | ptvcursor_new_subtree_levels(ptvc);
1367 |
1368 | subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1369 | subtree->tree = ptvc->tree;
1370 | subtree->it= NULL((void*)0);
1371 | ptvc->pushed_tree_index++;
1372 | return ptvcursor_set_subtree(ptvc, it, ett_subtree);
1373 | }
1374 |
1375 | /* pops a subtree */
1376 | void
1377 | ptvcursor_pop_subtree(ptvcursor_t *ptvc)
1378 | {
1379 | subtree_lvl *subtree;
1380 |
1381 | if (ptvc->pushed_tree_index <= 0)
1382 | return;
1383 |
1384 | ptvc->pushed_tree_index--;
1385 | subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1386 | if (subtree->it != NULL((void*)0))
1387 | proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
1388 |
1389 | ptvc->tree = subtree->tree;
1390 | }
1391 |
1392 | /* saves the current tvb offset and the item in the current subtree level */
1393 | static void
1394 | ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
1395 | {
1396 | subtree_lvl *subtree;
1397 |
1398 | 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", 1398, "ptvc->pushed_tree_index > 0" ))));
1399 |
1400 | subtree = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
1401 | subtree->it = it;
1402 | subtree->cursor_offset = ptvcursor_current_offset(ptvc);
1403 | }
1404 |
1405 | /* Creates a subtree and adds it to the cursor as the working tree but does not
1406 | * save the old working tree */
1407 | proto_tree *
1408 | ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1409 | {
1410 | ptvc->tree = proto_item_add_subtree(it, ett_subtree);
1411 | return ptvc->tree;
1412 | }
1413 |
1414 | static proto_tree *
1415 | ptvcursor_add_subtree_item(ptvcursor_t *ptvc, proto_item *it, int ett_subtree, int length)
1416 | {
1417 | ptvcursor_push_subtree(ptvc, it, ett_subtree);
1418 | if (length == SUBTREE_UNDEFINED_LENGTH-1)
1419 | ptvcursor_subtree_set_item(ptvc, it);
1420 | return ptvcursor_tree(ptvc);
1421 | }
1422 |
1423 | /* Add an item to the tree and create a subtree
1424 | * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1425 | * In this case, when the subtree will be closed, the parent item length will
1426 | * be equal to the advancement of the cursor since the creation of the subtree.
1427 | */
1428 | proto_tree *
1429 | ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, int length,
1430 | const unsigned encoding, int ett_subtree)
1431 | {
1432 | proto_item *it;
1433 |
1434 | it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
1435 | return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
1436 | }
1437 |
1438 | static proto_item *
1439 | proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, int start, int length);
1440 |
1441 | /* Add a text node to the tree and create a subtree
1442 | * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1443 | * In this case, when the subtree will be closed, the item length will be equal
1444 | * to the advancement of the cursor since the creation of the subtree.
1445 | */
1446 | proto_tree *
1447 | ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, int length,
1448 | int ett_subtree, const char *format, ...)
1449 | {
1450 | proto_item *pi;
1451 | va_list ap;
1452 | header_field_info *hfinfo;
1453 | proto_tree *tree;
1454 |
1455 | tree = ptvcursor_tree(ptvc);
1456 |
1457 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1458 |
1459 | 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", 1459 , __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", 1459, "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", 1459, "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", 1459, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
1460 |
1461 | pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
1462 | ptvcursor_current_offset(ptvc), length);
1463 |
1464 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 1464, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
1465 |
1466 | va_start(ap, format)__builtin_va_start(ap, format);
1467 | proto_tree_set_representation(pi, format, ap);
1468 | va_end(ap)__builtin_va_end(ap);
1469 |
1470 | return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
1471 | }
1472 |
1473 | /* Add a text-only node, leaving it to our caller to fill the text in */
1474 | static proto_item *
1475 | proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1476 | {
1477 | proto_item *pi;
1478 |
1479 | if (tree == NULL((void*)0))
1480 | return NULL((void*)0);
1481 |
1482 | pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
1483 |
1484 | return pi;
1485 | }
1486 |
1487 | /* (INTERNAL USE ONLY) Add a text-only node to the proto_tree */
1488 | proto_item *
1489 | proto_tree_add_text_internal(proto_tree *tree, tvbuff_t *tvb, int start, int length,
1490 | const char *format, ...)
1491 | {
1492 | proto_item *pi;
1493 | va_list ap;
1494 | header_field_info *hfinfo;
1495 |
1496 | if (length == -1) {
1497 | length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
1498 | } else {
1499 | tvb_ensure_bytes_exist(tvb, start, length);
1500 | }
1501 |
1502 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1503 |
1504 | 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", 1504 , __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", 1504, "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", 1504, "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", 1504, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
1505 |
1506 | pi = proto_tree_add_text_node(tree, tvb, start, length);
1507 |
1508 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 1508, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
1509 |
1510 | va_start(ap, format)__builtin_va_start(ap, format);
1511 | proto_tree_set_representation(pi, format, ap);
1512 | va_end(ap)__builtin_va_end(ap);
1513 |
1514 | return pi;
1515 | }
1516 |
1517 | /* (INTERNAL USE ONLY) Add a text-only node to the proto_tree (va_list version) */
1518 | proto_item *
1519 | proto_tree_add_text_valist_internal(proto_tree *tree, tvbuff_t *tvb, int start,
1520 | int length, const char *format, va_list ap)
1521 | {
1522 | proto_item *pi;
1523 | header_field_info *hfinfo;
1524 |
1525 | /* proto_tree_add_text_node calls proto_tree_add_pi() with the
1526 | * FT_NONE hf_text_only, which calls get_hfi_length, which adjusts
1527 | * the length to be what's in the tvbuff if length is -1, and the
1528 | * minimum of length and what's in the tvbuff if not.
1529 | */
1530 |
1531 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1532 |
1533 | 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", 1533 , __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", 1533, "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", 1533, "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", 1533, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
1534 |
1535 | pi = proto_tree_add_text_node(tree, tvb, start, length);
1536 |
1537 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 1537, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
1538 |
1539 | proto_tree_set_representation(pi, format, ap);
1540 |
1541 | return pi;
1542 | }
1543 |
1544 | /* Add a text-only node that creates a subtree underneath.
1545 | */
1546 | proto_tree *
1547 | proto_tree_add_subtree(proto_tree *tree, tvbuff_t *tvb, int start, int length, int idx, proto_item **tree_item, const char *text)
1548 | {
1549 | return proto_tree_add_subtree_format(tree, tvb, start, length, idx, tree_item, "%s", text);
1550 | }
1551 |
1552 | /* Add a text-only node that creates a subtree underneath.
1553 | */
1554 | proto_tree *
1555 | proto_tree_add_subtree_format(proto_tree *tree, tvbuff_t *tvb, int start, int length, int idx, proto_item **tree_item, const char *format, ...)
1556 | {
1557 | proto_tree *pt;
1558 | proto_item *pi;
1559 | va_list ap;
1560 |
1561 | va_start(ap, format)__builtin_va_start(ap, format);
1562 | pi = proto_tree_add_text_valist_internal(tree, tvb, start, length, format, ap);
1563 | va_end(ap)__builtin_va_end(ap);
1564 |
1565 | if (tree_item != NULL((void*)0))
1566 | *tree_item = pi;
1567 |
1568 | pt = proto_item_add_subtree(pi, idx);
1569 |
1570 | return pt;
1571 | }
1572 |
1573 | /* Add a text-only node for debugging purposes. The caller doesn't need
1574 | * to worry about tvbuff, start, or length. Debug message gets sent to
1575 | * STDOUT, too */
1576 | proto_item *
1577 | proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
1578 | {
1579 | proto_item *pi;
1580 | va_list ap;
1581 |
1582 | pi = proto_tree_add_text_node(tree, NULL((void*)0), 0, 0);
1583 |
1584 | if (pi) {
1585 | va_start(ap, format)__builtin_va_start(ap, format);
1586 | proto_tree_set_representation(pi, format, ap);
1587 | va_end(ap)__builtin_va_end(ap);
1588 | }
1589 | va_start(ap, format)__builtin_va_start(ap, format);
1590 | vprintf(format, ap);
1591 | va_end(ap)__builtin_va_end(ap);
1592 | printf("\n");
1593 |
1594 | return pi;
1595 | }
1596 |
1597 | proto_item *
1598 | proto_tree_add_format_text(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1599 | {
1600 | proto_item *pi;
1601 | header_field_info *hfinfo;
1602 |
1603 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1604 |
1605 | 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", 1605 , __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", 1605, "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", 1605, "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", 1605, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
1606 |
1607 | pi = proto_tree_add_text_node(tree, tvb, start, length);
1608 |
1609 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 1609, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
1610 |
1611 | proto_item_set_text(pi, "%s", tvb_format_text(tree->tree_data->pinfo->pool, tvb, start, length));
1612 |
1613 | return pi;
1614 | }
1615 |
1616 | proto_item *
1617 | proto_tree_add_format_wsp_text(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1618 | {
1619 | proto_item *pi;
1620 | header_field_info *hfinfo;
1621 | char *str;
1622 |
1623 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1624 |
1625 | 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", 1625 , __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", 1625, "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", 1625, "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", 1625, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
1626 |
1627 | pi = proto_tree_add_text_node(tree, tvb, start, length);
1628 |
1629 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 1629, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
1630 |
1631 | str = tvb_format_text_wsp(NULL((void*)0), tvb, start, length);
1632 | proto_item_set_text(pi, "%s", str);
1633 | wmem_free(NULL((void*)0), str);
1634 |
1635 | return pi;
1636 | }
1637 |
1638 | void proto_report_dissector_bug(const char *format, ...)
1639 | {
1640 | va_list args;
1641 |
1642 | if (wireshark_abort_on_dissector_bug) {
1643 | /*
1644 | * Try to have the error message show up in the crash
1645 | * information.
1646 | */
1647 | va_start(args, format)__builtin_va_start(args, format);
1648 | ws_vadd_crash_info(format, args);
1649 | va_end(args)__builtin_va_end(args);
1650 |
1651 | /*
1652 | * Print the error message.
1653 | */
1654 | va_start(args, format)__builtin_va_start(args, format);
1655 | vfprintf(stderrstderr, format, args);
1656 | va_end(args)__builtin_va_end(args);
1657 | putc('\n', stderrstderr);
1658 |
1659 | /*
1660 | * And crash.
1661 | */
1662 | abort();
1663 | } else {
1664 | va_start(args, format)__builtin_va_start(args, format);
1665 | VTHROW_FORMATTED(DissectorError, format, args)except_vthrowf(1, (6), format, args);
1666 | va_end(args)__builtin_va_end(args);
1667 | ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1667 , __func__, "assertion \"not reached\" failed"); /* GCC 12 with ASAN needs this. */
1668 | }
1669 | }
1670 |
1671 | /* We could probably get away with changing is_error to a minimum length value. */
1672 | static void
1673 | report_type_length_mismatch(proto_tree *tree, const char *descr, int length, bool_Bool is_error)
1674 | {
1675 | if (is_error) {
1676 | expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_error, "Trying to fetch %s with length %d", descr, length);
1677 | } else {
1678 | expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_warn, "Trying to fetch %s with length %d", descr, length);
1679 | }
1680 |
1681 | if (is_error) {
1682 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
1683 | }
1684 | }
1685 |
1686 | static uint32_t
1687 | get_uint_value(proto_tree *tree, tvbuff_t *tvb, int offset, int length, const unsigned encoding)
1688 | {
1689 | uint32_t value;
1690 | bool_Bool length_error;
1691 |
1692 | switch (length) {
1693 |
1694 | case 1:
1695 | value = tvb_get_uint8(tvb, offset);
1696 | if (encoding & ENC_ZIGBEE0x40000000) {
1697 | if (value == 0xFF) { /* Invalid Zigbee length, set to 0 */
1698 | value = 0;
1699 | }
1700 | }
1701 | break;
1702 |
1703 | case 2:
1704 | value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohs(tvb, offset)
1705 | : tvb_get_ntohs(tvb, offset);
1706 | if (encoding & ENC_ZIGBEE0x40000000) {
1707 | if (value == 0xFFFF) { /* Invalid Zigbee length, set to 0 */
1708 | value = 0;
1709 | }
1710 | }
1711 | break;
1712 |
1713 | case 3:
1714 | value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letoh24(tvb, offset)
1715 | : tvb_get_ntoh24(tvb, offset);
1716 | break;
1717 |
1718 | case 4:
1719 | value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1720 | : tvb_get_ntohl(tvb, offset);
1721 | break;
1722 |
1723 | default:
1724 | if (length < 1) {
1725 | length_error = true1;
1726 | value = 0;
1727 | } else {
1728 | length_error = false0;
1729 | value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1730 | : tvb_get_ntohl(tvb, offset);
1731 | }
1732 | report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1733 | break;
1734 | }
1735 | return value;
1736 | }
1737 |
1738 | static inline uint64_t
1739 | get_uint64_value(proto_tree *tree, tvbuff_t *tvb, int offset, unsigned length, const unsigned encoding)
1740 | {
1741 | uint64_t value;
1742 |
1743 | value = tvb_get_uint64_with_length(tvb, offset, length, encoding);
1744 |
1745 | if (length < 1 || length > 8) {
1746 | report_type_length_mismatch(tree, "an unsigned integer", length, (length < 1));
1747 | }
1748 |
1749 | return value;
1750 | }
1751 |
1752 | static int32_t
1753 | get_int_value(proto_tree *tree, tvbuff_t *tvb, int offset, int length, const unsigned encoding)
1754 | {
1755 | int32_t value;
1756 | bool_Bool length_error;
1757 |
1758 | switch (length) {
1759 |
1760 | case 1:
1761 | value = tvb_get_int8(tvb, offset);
1762 | break;
1763 |
1764 | case 2:
1765 | value = encoding ? tvb_get_letohis(tvb, offset)
1766 | : tvb_get_ntohis(tvb, offset);
1767 | break;
1768 |
1769 | case 3:
1770 | value = encoding ? tvb_get_letohi24(tvb, offset)
1771 | : tvb_get_ntohi24(tvb, offset);
1772 | break;
1773 |
1774 | case 4:
1775 | value = encoding ? tvb_get_letohil(tvb, offset)
1776 | : tvb_get_ntohil(tvb, offset);
1777 | break;
1778 |
1779 | default:
1780 | if (length < 1) {
1781 | length_error = true1;
1782 | value = 0;
1783 | } else {
1784 | length_error = false0;
1785 | value = encoding ? tvb_get_letohil(tvb, offset)
1786 | : tvb_get_ntohil(tvb, offset);
1787 | }
1788 | report_type_length_mismatch(tree, "a signed integer", length, length_error);
1789 | break;
1790 | }
1791 | return value;
1792 | }
1793 |
1794 | /* Note: this returns an unsigned int64, but with the appropriate bit(s) set to
1795 | * be cast-able as a int64_t. This is weird, but what the code has always done.
1796 | */
1797 | static inline uint64_t
1798 | get_int64_value(proto_tree *tree, tvbuff_t *tvb, int start, unsigned length, const unsigned encoding)
1799 | {
1800 | uint64_t value = get_uint64_value(tree, tvb, start, length, encoding);
1801 |
1802 | switch (length) {
1803 | case 7:
1804 | value = ws_sign_ext64(value, 56);
1805 | break;
1806 | case 6:
1807 | value = ws_sign_ext64(value, 48);
1808 | break;
1809 | case 5:
1810 | value = ws_sign_ext64(value, 40);
1811 | break;
1812 | case 4:
1813 | value = ws_sign_ext64(value, 32);
1814 | break;
1815 | case 3:
1816 | value = ws_sign_ext64(value, 24);
1817 | break;
1818 | case 2:
1819 | value = ws_sign_ext64(value, 16);
1820 | break;
1821 | case 1:
1822 | value = ws_sign_ext64(value, 8);
1823 | break;
1824 | }
1825 |
1826 | return value;
1827 | }
1828 |
1829 | /* For FT_STRING */
1830 | static inline const uint8_t *
1831 | get_string_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1832 | int length, int *ret_length, const unsigned encoding)
1833 | {
1834 | if (length == -1) {
1835 | length = tvb_ensure_captured_length_remaining(tvb, start);
1836 | }
1837 | *ret_length = length;
1838 | return tvb_get_string_enc(scope, tvb, start, length, encoding);
1839 | }
1840 |
1841 | /* For FT_STRINGZ */
1842 | static inline const uint8_t *
1843 | get_stringz_value(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb,
1844 | int start, int length, int *ret_length, const unsigned encoding)
1845 | {
1846 | const uint8_t *value;
1847 |
1848 | if (length < -1) {
1849 | report_type_length_mismatch(tree, "a string", length, true1);
1850 | }
1851 |
1852 | /* XXX - Ideally, every "null-terminated string which fits into a
1853 | * known length" should be either FT_STRINGZPAD or FT_STRINGZTRUNC
1854 | * as appropriate, not a FT_STRINGZ. If so, then we could always call
1855 | * tvb_get_stringz_enc here. Failing that, we could treat length 0
1856 | * as unknown length as well (since there is a trailing '\0', the real
1857 | * length is never zero), allowing switching to unsigned lengths.
1858 | */
1859 | if (length == -1) {
1860 | /* This can throw an exception */
1861 | value = tvb_get_stringz_enc(scope, tvb, start, (unsigned*)&length, encoding);
1862 | } else {
1863 | /* In this case, length signifies the length of the string.
1864 | *
1865 | * This could either be a null-padded string, which doesn't
1866 | * necessarily have a '\0' at the end, or a null-terminated
1867 | * string, with a trailing '\0'. (Yes, there are cases
1868 | * where you have a string that's both counted and null-
1869 | * terminated.)
1870 | *
1871 | * In the first case, we must allocate a buffer of length
1872 | * "length+1", to make room for a trailing '\0'.
1873 | *
1874 | * In the second case, we don't assume that there is a
1875 | * trailing '\0' there, as the packet might be malformed.
1876 | * (XXX - should we throw an exception if there's no
1877 | * trailing '\0'?) Therefore, we allocate a buffer of
1878 | * length "length+1", and put in a trailing '\0', just to
1879 | * be safe.
1880 | *
1881 | * (XXX - this would change if we made string values counted
1882 | * rather than null-terminated.)
1883 | */
1884 | value = tvb_get_string_enc(scope, tvb, start, length, encoding);
1885 | }
1886 | *ret_length = length;
1887 | return value;
1888 | }
1889 |
1890 | /* For FT_UINT_STRING */
1891 | static inline const uint8_t *
1892 | get_uint_string_value(wmem_allocator_t *scope, proto_tree *tree,
1893 | tvbuff_t *tvb, int start, int length, int *ret_length,
1894 | const unsigned encoding)
1895 | {
1896 | uint32_t n;
1897 | const uint8_t *value;
1898 |
1899 | /* I believe it's ok if this is called with a NULL tree */
1900 | n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
1901 | value = tvb_get_string_enc(scope, tvb, start + length, n, encoding);
1902 | length += n;
1903 | *ret_length = length;
1904 | return value;
1905 | }
1906 |
1907 | /* For FT_STRINGZPAD */
1908 | static inline const uint8_t *
1909 | get_stringzpad_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1910 | int length, int *ret_length, const unsigned encoding)
1911 | {
1912 | /*
1913 | * XXX - currently, string values are null-
1914 | * terminated, so a "zero-padded" string
1915 | * isn't special. If we represent string
1916 | * values as something that includes a counted
1917 | * array of bytes, we'll need to strip the
1918 | * trailing NULs.
1919 | */
1920 | if (length == -1) {
1921 | length = tvb_ensure_captured_length_remaining(tvb, start);
1922 | }
1923 | *ret_length = length;
1924 | return tvb_get_string_enc(scope, tvb, start, length, encoding);
1925 | }
1926 |
1927 | /* For FT_STRINGZTRUNC */
1928 | static inline const uint8_t *
1929 | get_stringztrunc_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1930 | int length, int *ret_length, const unsigned encoding)
1931 | {
1932 | /*
1933 | * XXX - currently, string values are null-
1934 | * terminated, so a "zero-truncated" string
1935 | * isn't special. If we represent string
1936 | * values as something that includes a counted
1937 | * array of bytes, we'll need to strip everything
1938 | * starting with the terminating NUL.
1939 | */
1940 | if (length == -1) {
1941 | length = tvb_ensure_captured_length_remaining(tvb, start);
1942 | }
1943 | *ret_length = length;
1944 | return tvb_get_string_enc(scope, tvb, start, length, encoding);
1945 | }
1946 |
1947 | /*
1948 | * Deltas between the epochs for various non-UN*X time stamp formats and
1949 | * the January 1, 1970, 00:00:00 (proleptic?) UTC epoch for the UN*X time
1950 | * stamp format.
1951 | */
1952 |
1953 | /*
1954 | * NTP Era 0: the epoch is January 1, 1900, 00:00:00 (proleptic?) UTC.
1955 | * XXX - if it's OK if this is unsigned, can we just use
1956 | * EPOCH_DELTA_1900_01_01_00_00_00_UTC?
1957 | */
1958 | #define NTP_TIMEDIFF1900TO1970SEC2208988800L INT64_C(2208988800)2208988800L
1959 |
1960 | /*
1961 | * NTP Era 1: the epoch is February 7, 2036, 06:28:16 UTC.
1962 | */
1963 | #define NTP_TIMEDIFF1970TO2036SEC2085978496L INT64_C(2085978496)2085978496L
1964 |
1965 | /* this can be called when there is no tree, so tree may be null */
1966 | static void
1967 | get_time_value(proto_tree *tree, tvbuff_t *tvb, const int start,
1968 | const int length, const unsigned encoding, nstime_t *time_stamp,
1969 | const bool_Bool is_relative)
1970 | {
1971 | uint32_t tmpsecs;
1972 | uint64_t tmp64secs;
1973 | uint64_t todusecs;
1974 |
1975 | switch (encoding) {
1976 |
1977 | case ENC_TIME_SECS_NSECS0x00000000|ENC_BIG_ENDIAN0x00000000:
1978 | /*
1979 | * If the length is 16, 8-byte seconds, followed
1980 | * by 8-byte fractional time in nanoseconds,
1981 | * both big-endian.
1982 | *
1983 | * If the length is 12, 8-byte seconds, followed
1984 | * by 4-byte fractional time in nanoseconds,
1985 | * both big-endian.
1986 | *
1987 | * If the length is 8, 4-byte seconds, followed
1988 | * by 4-byte fractional time in nanoseconds,
1989 | * both big-endian.
1990 | *
1991 | * For absolute times, the seconds are seconds
1992 | * since the UN*X epoch.
1993 | */
1994 | if (length == 16) {
1995 | time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
1996 | time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8);
1997 | } else if (length == 12) {
1998 | time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
1999 | time_stamp->nsecs = tvb_get_ntohl(tvb, start+8);
2000 | } else if (length == 8) {
2001 | time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2002 | time_stamp->nsecs = tvb_get_ntohl(tvb, start+4);
2003 | } else if (length == 4) {
2004 | /*
2005 | * Backwards compatibility.
2006 | * ENC_TIME_SECS_NSECS is 0; using
2007 | * ENC_BIG_ENDIAN by itself with a 4-byte
2008 | * time-in-seconds value was done in the
2009 | * past.
2010 | */
2011 | time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2012 | time_stamp->nsecs = 0;
2013 | } else {
2014 | time_stamp->secs = 0;
2015 | time_stamp->nsecs = 0;
2016 | report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2017 | }
2018 | break;
2019 |
2020 | case ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000:
2021 | /*
2022 | * If the length is 16, 8-byte seconds, followed
2023 | * by 8-byte fractional time in nanoseconds,
2024 | * both little-endian.
2025 | *
2026 | * If the length is 12, 8-byte seconds, followed
2027 | * by 4-byte fractional time in nanoseconds,
2028 | * both little-endian.
2029 | *
2030 | * If the length is 8, 4-byte seconds, followed
2031 | * by 4-byte fractional time in nanoseconds,
2032 | * both little-endian.
2033 | *
2034 | * For absolute times, the seconds are seconds
2035 | * since the UN*X epoch.
2036 | */
2037 | if (length == 16) {
2038 | time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2039 | time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8);
2040 | } else if (length == 12) {
2041 | time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2042 | time_stamp->nsecs = tvb_get_letohl(tvb, start+8);
2043 | } else if (length == 8) {
2044 | time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2045 | time_stamp->nsecs = tvb_get_letohl(tvb, start+4);
2046 | } else if (length == 4) {
2047 | /*
2048 | * Backwards compatibility.
2049 | * ENC_TIME_SECS_NSECS is 0; using
2050 | * ENC_LITTLE_ENDIAN by itself with a 4-byte
2051 | * time-in-seconds value was done in the
2052 | * past.
2053 | */
2054 | time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2055 | time_stamp->nsecs = 0;
2056 | } else {
2057 | time_stamp->secs = 0;
2058 | time_stamp->nsecs = 0;
2059 | report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2060 | }
2061 | break;
2062 |
2063 | case ENC_TIME_NTP0x00000002|ENC_BIG_ENDIAN0x00000000:
2064 | /*
2065 | * NTP time stamp, big-endian.
2066 | * Only supported for absolute times.
2067 | */
2068 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2068, "!is_relative" ))));
2069 |
2070 | /* We need a temporary variable here so the unsigned math
2071 | * works correctly (for years > 2036 according to RFC 2030
2072 | * chapter 3).
2073 | *
2074 | * If bit 0 is set, the UTC time is in the range 1968-2036 and
2075 | * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2076 | * If bit 0 is not set, the time is in the range 2036-2104 and
2077 | * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2078 | */
2079 | tmpsecs = tvb_get_ntohl(tvb, start);
2080 | if ((tmpsecs & 0x80000000) != 0)
2081 | time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2082 | else
2083 | time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2084 |
2085 | if (length == 8) {
2086 | tmp64secs = tvb_get_ntoh64(tvb, start);
2087 | if (tmp64secs == 0) {
2088 | //This is "NULL" time
2089 | time_stamp->secs = 0;
2090 | time_stamp->nsecs = 0;
2091 | } else {
2092 | /*
2093 | * Convert 1/2^32s of a second to
2094 | * nanoseconds.
2095 | */
2096 | time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2097 | }
2098 | } else if (length == 4) {
2099 | /*
2100 | * Backwards compatibility.
2101 | */
2102 | if (tmpsecs == 0) {
2103 | //This is "NULL" time
2104 | time_stamp->secs = 0;
2105 | }
2106 | time_stamp->nsecs = 0;
2107 | } else {
2108 | time_stamp->secs = 0;
2109 | time_stamp->nsecs = 0;
2110 | report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2111 | }
2112 | break;
2113 |
2114 | case ENC_TIME_NTP0x00000002|ENC_LITTLE_ENDIAN0x80000000:
2115 | /*
2116 | * NTP time stamp, little-endian.
2117 | * Only supported for absolute times.
2118 | *
2119 | * NTP doesn't use this, because it's an Internet format
2120 | * and hence big-endian. Any implementation must decide
2121 | * whether the NTP timestamp is a 64-bit unsigned fixed
2122 | * point number (RFC 1305, RFC 4330) or a 64-bit struct
2123 | * with a 32-bit unsigned seconds field followed by a
2124 | * 32-bit fraction field (cf. RFC 5905, which obsoletes
2125 | * the previous two).
2126 | *
2127 | * XXX: We do the latter, but no dissector uses this format.
2128 | * OTOH, ERF timestamps do the former, so perhaps we
2129 | * should switch the interpretation so that packet-erf.c
2130 | * could use this directly?
2131 | */
2132 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2132, "!is_relative" ))));
2133 |
2134 | /* We need a temporary variable here so the unsigned math
2135 | * works correctly (for years > 2036 according to RFC 2030
2136 | * chapter 3).
2137 | *
2138 | * If bit 0 is set, the UTC time is in the range 1968-2036 and
2139 | * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2140 | * If bit 0 is not set, the time is in the range 2036-2104 and
2141 | * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2142 | */
2143 | tmpsecs = tvb_get_letohl(tvb, start);
2144 | if ((tmpsecs & 0x80000000) != 0)
2145 | time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2146 | else
2147 | time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2148 |
2149 | if (length == 8) {
2150 | tmp64secs = tvb_get_letoh64(tvb, start);
2151 | if (tmp64secs == 0) {
2152 | //This is "NULL" time
2153 | time_stamp->secs = 0;
2154 | time_stamp->nsecs = 0;
2155 | } else {
2156 | /*
2157 | * Convert 1/2^32s of a second to
2158 | * nanoseconds.
2159 | */
2160 | time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2161 | }
2162 | } else if (length == 4) {
2163 | /*
2164 | * Backwards compatibility.
2165 | */
2166 | if (tmpsecs == 0) {
2167 | //This is "NULL" time
2168 | time_stamp->secs = 0;
2169 | }
2170 | time_stamp->nsecs = 0;
2171 | } else {
2172 | time_stamp->secs = 0;
2173 | time_stamp->nsecs = 0;
2174 | report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2175 | }
2176 | break;
2177 |
2178 | case ENC_TIME_TOD0x00000004|ENC_BIG_ENDIAN0x00000000:
2179 | /*
2180 | * S/3x0 and z/Architecture TOD clock time stamp,
2181 | * big-endian. The epoch is January 1, 1900,
2182 | * 00:00:00 (proleptic?) UTC.
2183 | *
2184 | * Only supported for absolute times.
2185 | */
2186 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2186, "!is_relative" ))));
2187 | DISSECTOR_ASSERT(length == 8)((void) ((length == 8) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2187, "length == 8" ))));
2188 |
2189 | if (length == 8) {
2190 | todusecs = tvb_get_ntoh64(tvb, start) >> 12;
2191 | time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2192 | time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2193 | } else {
2194 | time_stamp->secs = 0;
2195 | time_stamp->nsecs = 0;
2196 | report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2197 | }
2198 | break;
2199 |
2200 | case ENC_TIME_TOD0x00000004|ENC_LITTLE_ENDIAN0x80000000:
2201 | /*
2202 | * S/3x0 and z/Architecture TOD clock time stamp,
2203 | * little-endian. The epoch is January 1, 1900,
2204 | * 00:00:00 (proleptic?) UTC.
2205 | *
2206 | * Only supported for absolute times.
2207 | */
2208 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2208, "!is_relative" ))));
2209 |
2210 | if (length == 8) {
2211 | todusecs = tvb_get_letoh64(tvb, start) >> 12 ;
2212 | time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2213 | time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2214 | } else {
2215 | time_stamp->secs = 0;
2216 | time_stamp->nsecs = 0;
2217 | report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2218 | }
2219 | break;
2220 |
2221 | case ENC_TIME_RTPS0x00000008|ENC_BIG_ENDIAN0x00000000:
2222 | /*
2223 | * Time stamp using the same seconds/fraction format
2224 | * as NTP, but with the origin of the time stamp being
2225 | * the UNIX epoch rather than the NTP epoch; big-
2226 | * endian.
2227 | *
2228 | * Only supported for absolute times.
2229 | */
2230 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2230, "!is_relative" ))));
2231 |
2232 | if (length == 8) {
2233 | time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2234 | /*
2235 | * Convert 1/2^32s of a second to nanoseconds.
2236 | */
2237 | time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2238 | } else {
2239 | time_stamp->secs = 0;
2240 | time_stamp->nsecs = 0;
2241 | report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2242 | }
2243 | break;
2244 |
2245 | case ENC_TIME_RTPS0x00000008|ENC_LITTLE_ENDIAN0x80000000:
2246 | /*
2247 | * Time stamp using the same seconds/fraction format
2248 | * as NTP, but with the origin of the time stamp being
2249 | * the UNIX epoch rather than the NTP epoch; little-
2250 | * endian.
2251 | *
2252 | * Only supported for absolute times.
2253 | *
2254 | * The RTPS specification explicitly supports Little
2255 | * Endian encoding. In one place, it states that its
2256 | * Time_t representation "is the one defined by ...
2257 | * RFC 1305", but in another explicitly defines it as
2258 | * a struct consisting of an 32 bit unsigned seconds
2259 | * field and a 32 bit unsigned fraction field, not a 64
2260 | * bit fixed point, so we do that here.
2261 | * https://www.omg.org/spec/DDSI-RTPS/2.5/PDF
2262 | */
2263 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2263, "!is_relative" ))));
2264 |
2265 | if (length == 8) {
2266 | time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2267 | /*
2268 | * Convert 1/2^32s of a second to nanoseconds.
2269 | */
2270 | time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2271 | } else {
2272 | time_stamp->secs = 0;
2273 | time_stamp->nsecs = 0;
2274 | report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2275 | }
2276 | break;
2277 |
2278 | case ENC_TIME_MIP60x00000024 | ENC_BIG_ENDIAN0x00000000:
2279 | /*
2280 | * MIP6 time stamp, big-endian.
2281 | * A 64-bit unsigned integer field containing a timestamp. The
2282 | * value indicates the number of seconds since January 1, 1970,
2283 | * 00:00 UTC, by using a fixed point format. In this format, the
2284 | * integer number of seconds is contained in the first 48 bits of
2285 | * the field, and the remaining 16 bits indicate the number of
2286 | * 1/65536 fractions of a second.
2287 |
2288 | * Only supported for absolute times.
2289 | */
2290 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2290, "!is_relative" ))));
2291 |
2292 | if (length == 8) {
2293 | /* We need a temporary variable here so the casting and fractions
2294 | * of a second work correctly.
2295 | */
2296 | tmp64secs = tvb_get_ntoh48(tvb, start);
2297 | tmpsecs = tvb_get_ntohs(tvb, start + 6);
2298 | tmpsecs <<= 16;
2299 |
2300 | if ((tmp64secs == 0) && (tmpsecs == 0)) {
2301 | //This is "NULL" time
2302 | time_stamp->secs = 0;
2303 | time_stamp->nsecs = 0;
2304 | } else {
2305 | time_stamp->secs = (time_t)tmp64secs;
2306 | time_stamp->nsecs = (int)((tmpsecs / 4294967296.0) * 1000000000);
2307 | }
2308 | } else {
2309 | time_stamp->secs = 0;
2310 | time_stamp->nsecs = 0;
2311 | report_type_length_mismatch(tree, "an NTP time stamp", length, (length != 8));
2312 | }
2313 | break;
2314 |
2315 | case ENC_TIME_SECS_USECS0x00000010|ENC_BIG_ENDIAN0x00000000:
2316 | /*
2317 | * If the length is 16, 8-byte seconds, followed
2318 | * by 8-byte fractional time in microseconds,
2319 | * both big-endian.
2320 | *
2321 | * If the length is 12, 8-byte seconds, followed
2322 | * by 4-byte fractional time in microseconds,
2323 | * both big-endian.
2324 | *
2325 | * If the length is 8, 4-byte seconds, followed
2326 | * by 4-byte fractional time in microseconds,
2327 | * both big-endian.
2328 | *
2329 | * For absolute times, the seconds are seconds
2330 | * since the UN*X epoch.
2331 | */
2332 | if (length == 16) {
2333 | time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2334 | time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8)*1000;
2335 | } else if (length == 12) {
2336 | time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2337 | time_stamp->nsecs = tvb_get_ntohl(tvb, start+8)*1000;
2338 | } else if (length == 8) {
2339 | time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2340 | time_stamp->nsecs = tvb_get_ntohl(tvb, start+4)*1000;
2341 | } else {
2342 | time_stamp->secs = 0;
2343 | time_stamp->nsecs = 0;
2344 | report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2345 | }
2346 | break;
2347 |
2348 | case ENC_TIME_SECS_USECS0x00000010|ENC_LITTLE_ENDIAN0x80000000:
2349 | /*
2350 | * If the length is 16, 8-byte seconds, followed
2351 | * by 8-byte fractional time in microseconds,
2352 | * both little-endian.
2353 | *
2354 | * If the length is 12, 8-byte seconds, followed
2355 | * by 4-byte fractional time in microseconds,
2356 | * both little-endian.
2357 | *
2358 | * If the length is 8, 4-byte seconds, followed
2359 | * by 4-byte fractional time in microseconds,
2360 | * both little-endian.
2361 | *
2362 | * For absolute times, the seconds are seconds
2363 | * since the UN*X epoch.
2364 | */
2365 | if (length == 16) {
2366 | time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2367 | time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8)*1000;
2368 | } else if (length == 12) {
2369 | time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2370 | time_stamp->nsecs = tvb_get_letohl(tvb, start+8)*1000;
2371 | } else if (length == 8) {
2372 | time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2373 | time_stamp->nsecs = tvb_get_letohl(tvb, start+4)*1000;
2374 | } else {
2375 | time_stamp->secs = 0;
2376 | time_stamp->nsecs = 0;
2377 | report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2378 | }
2379 | break;
2380 |
2381 | case ENC_TIME_SECS0x00000012|ENC_BIG_ENDIAN0x00000000:
2382 | case ENC_TIME_SECS0x00000012|ENC_LITTLE_ENDIAN0x80000000:
2383 | /*
2384 | * Seconds, 1 to 8 bytes.
2385 | * For absolute times, it's seconds since the
2386 | * UN*X epoch.
2387 | */
2388 | if (length >= 1 && length <= 8) {
2389 | time_stamp->secs = (time_t)get_uint64_value(tree, tvb, start, length, encoding);
2390 | time_stamp->nsecs = 0;
2391 | } else {
2392 | time_stamp->secs = 0;
2393 | time_stamp->nsecs = 0;
2394 | report_type_length_mismatch(tree, "a time-in-seconds time stamp", length, (length < 4));
2395 | }
2396 | break;
2397 |
2398 | case ENC_TIME_MSECS0x00000014|ENC_BIG_ENDIAN0x00000000:
2399 | case ENC_TIME_MSECS0x00000014|ENC_LITTLE_ENDIAN0x80000000:
2400 | /*
2401 | * Milliseconds, 1 to 8 bytes.
2402 | * For absolute times, it's milliseconds since the
2403 | * UN*X epoch.
2404 | */
2405 | if (length >= 1 && length <= 8) {
2406 | uint64_t msecs;
2407 |
2408 | msecs = get_uint64_value(tree, tvb, start, length, encoding);
2409 | time_stamp->secs = (time_t)(msecs / 1000);
2410 | time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2411 | } else {
2412 | time_stamp->secs = 0;
2413 | time_stamp->nsecs = 0;
2414 | report_type_length_mismatch(tree, "a time-in-milliseconds time stamp", length, (length < 4));
2415 | }
2416 | break;
2417 |
2418 | case ENC_TIME_USECS0x00000030|ENC_BIG_ENDIAN0x00000000:
2419 | case ENC_TIME_USECS0x00000030|ENC_LITTLE_ENDIAN0x80000000:
2420 | /*
2421 | * Microseconds, 1 to 8 bytes.
2422 | * For absolute times, it's microseconds since the
2423 | * UN*X epoch.
2424 | */
2425 | if (length >= 1 && length <= 8) {
2426 | uint64_t usecs;
2427 |
2428 | usecs = get_uint64_value(tree, tvb, start, length, encoding);
2429 | time_stamp->secs = (time_t)(usecs / 1000000);
2430 | time_stamp->nsecs = (int)(usecs % 1000000)*1000;
2431 | } else {
2432 | time_stamp->secs = 0;
2433 | time_stamp->nsecs = 0;
2434 | report_type_length_mismatch(tree, "a time-in-microseconds time stamp", length, (length < 4));
2435 | }
2436 | break;
2437 |
2438 | case ENC_TIME_NSECS0x00000028|ENC_BIG_ENDIAN0x00000000:
2439 | case ENC_TIME_NSECS0x00000028|ENC_LITTLE_ENDIAN0x80000000:
2440 | /*
2441 | * nanoseconds, 1 to 8 bytes.
2442 | * For absolute times, it's nanoseconds since the
2443 | * UN*X epoch.
2444 | */
2445 |
2446 | if (length >= 1 && length <= 8) {
2447 | uint64_t nsecs;
2448 |
2449 | nsecs = get_uint64_value(tree, tvb, start, length, encoding);
2450 | time_stamp->secs = (time_t)(nsecs / 1000000000);
2451 | time_stamp->nsecs = (int)(nsecs % 1000000000);
2452 | } else {
2453 | time_stamp->secs = 0;
2454 | time_stamp->nsecs = 0;
2455 | report_type_length_mismatch(tree, "a time-in-nanoseconds time stamp", length, (length < 4));
2456 | }
2457 | break;
2458 |
2459 | case ENC_TIME_RFC_39710x00000020|ENC_BIG_ENDIAN0x00000000:
2460 | /*
2461 | * 1/64ths of a second since the UN*X epoch,
2462 | * big-endian.
2463 | *
2464 | * Only supported for absolute times.
2465 | */
2466 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2466, "!is_relative" ))));
2467 |
2468 | if (length == 8) {
2469 | /*
2470 | * The upper 48 bits are seconds since the
2471 | * UN*X epoch.
2472 | */
2473 | time_stamp->secs = (time_t)tvb_get_ntoh48(tvb, start);
2474 | /*
2475 | * The lower 16 bits are 1/2^16s of a second;
2476 | * convert them to nanoseconds.
2477 | *
2478 | * XXX - this may give the impression of higher
2479 | * precision than you actually get.
2480 | */
2481 | time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohs(tvb, start+6)/65536.0));
2482 | } else {
2483 | time_stamp->secs = 0;
2484 | time_stamp->nsecs = 0;
2485 | report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2486 | }
2487 | break;
2488 |
2489 | case ENC_TIME_RFC_39710x00000020|ENC_LITTLE_ENDIAN0x80000000:
2490 | /*
2491 | * 1/64ths of a second since the UN*X epoch,
2492 | * little-endian.
2493 | *
2494 | * Only supported for absolute times.
2495 | */
2496 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2496, "!is_relative" ))));
2497 |
2498 | if (length == 8) {
2499 | /*
2500 | * XXX - this is assuming that, if anybody
2501 | * were ever to use this format - RFC 3971
2502 | * doesn't, because that's an Internet
2503 | * protocol, and those use network byte
2504 | * order, i.e. big-endian - they'd treat it
2505 | * as a 64-bit count of 1/2^16s of a second,
2506 | * putting the upper 48 bits at the end.
2507 | *
2508 | * The lower 48 bits are seconds since the
2509 | * UN*X epoch.
2510 | */
2511 | time_stamp->secs = (time_t)tvb_get_letoh48(tvb, start+2);
2512 | /*
2513 | * The upper 16 bits are 1/2^16s of a second;
2514 | * convert them to nanoseconds.
2515 | *
2516 | * XXX - this may give the impression of higher
2517 | * precision than you actually get.
2518 | */
2519 | time_stamp->nsecs = (int)(1000000000*(tvb_get_letohs(tvb, start)/65536.0));
2520 | } else {
2521 | time_stamp->secs = 0;
2522 | time_stamp->nsecs = 0;
2523 | report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2524 | }
2525 | break;
2526 |
2527 | case ENC_TIME_SECS_NTP0x00000018|ENC_BIG_ENDIAN0x00000000:
2528 | /*
2529 | * NTP time stamp, with 1-second resolution (i.e.,
2530 | * seconds since the NTP epoch), big-endian.
2531 | * Only supported for absolute times.
2532 | */
2533 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2533, "!is_relative" ))));
2534 |
2535 | if (length == 4) {
2536 | /*
2537 | * We need a temporary variable here so the unsigned math
2538 | * works correctly (for years > 2036 according to RFC 2030
2539 | * chapter 3).
2540 | *
2541 | * If bit 0 is set, the UTC time is in the range 1968-2036 and
2542 | * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2543 | * If bit 0 is not set, the time is in the range 2036-2104 and
2544 | * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2545 | */
2546 | tmpsecs = tvb_get_ntohl(tvb, start);
2547 | if ((tmpsecs & 0x80000000) != 0)
2548 | time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2549 | else
2550 | time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2551 | time_stamp->nsecs = 0;
2552 | } else {
2553 | time_stamp->secs = 0;
2554 | time_stamp->nsecs = 0;
2555 | report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2556 | }
2557 | break;
2558 |
2559 | case ENC_TIME_SECS_NTP0x00000018|ENC_LITTLE_ENDIAN0x80000000:
2560 | /*
2561 | * NTP time stamp, with 1-second resolution (i.e.,
2562 | * seconds since the NTP epoch), little-endian.
2563 | * Only supported for absolute times.
2564 | */
2565 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2565, "!is_relative" ))));
2566 |
2567 | /*
2568 | * We need a temporary variable here so the unsigned math
2569 | * works correctly (for years > 2036 according to RFC 2030
2570 | * chapter 3).
2571 | *
2572 | * If bit 0 is set, the UTC time is in the range 1968-2036 and
2573 | * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2574 | * If bit 0 is not set, the time is in the range 2036-2104 and
2575 | * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2576 | */
2577 | if (length == 4) {
2578 | tmpsecs = tvb_get_letohl(tvb, start);
2579 | if ((tmpsecs & 0x80000000) != 0)
2580 | time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2581 | else
2582 | time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2583 | time_stamp->nsecs = 0;
2584 | } else {
2585 | time_stamp->secs = 0;
2586 | time_stamp->nsecs = 0;
2587 | report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2588 | }
2589 | break;
2590 |
2591 | case ENC_TIME_MSEC_NTP0x00000022 | ENC_BIG_ENDIAN0x00000000:
2592 | /*
2593 | * Milliseconds, 6 to 8 bytes.
2594 | * For absolute times, it's milliseconds since the
2595 | * NTP epoch.
2596 | *
2597 | * ETSI TS 129.274 8.119 defines this as:
2598 | * "a 48 bit unsigned integer in network order format
2599 | * ...encoded as the number of milliseconds since
2600 | * 00:00:00 January 1, 1900 00:00 UTC, i.e. as the
2601 | * rounded value of 1000 x the value of the 64-bit
2602 | * timestamp (Seconds + (Fraction / (1<<32))) defined
2603 | * in clause 6 of IETF RFC 5905."
2604 | *
2605 | * Taken literally, the part after "i.e." would
2606 | * mean that the value rolls over before reaching
2607 | * 2^32 * 1000 = 4294967296000 = 0x3e800000000
2608 | * when the 64 bit timestamp rolls over, and we have
2609 | * to pick an NTP Era equivalence class to support
2610 | * (such as 1968-01-20 to 2104-02-06).
2611 | *
2612 | * OTOH, the extra room might be used to store Era
2613 | * information instead, in which case times until
2614 | * 10819-08-03 can be represented with 6 bytes without
2615 | * ambiguity. We handle both implementations, and assume
2616 | * that times before 1968-01-20 are not represented.
2617 | *
2618 | * Only 6 bytes or more makes sense as an absolute
2619 | * time. 5 bytes or fewer could express a span of
2620 | * less than 35 years, either 1900-1934 or 2036-2070.
2621 | */
2622 | if (length >= 6 && length <= 8) {
2623 | uint64_t msecs;
2624 |
2625 | msecs = get_uint64_value(tree, tvb, start, length, encoding);
2626 | tmp64secs = (msecs / 1000);
2627 | /*
2628 | * Assume that times in the first half of NTP
2629 | * Era 0 really represent times in the NTP
2630 | * Era 1.
2631 | */
2632 | if (tmp64secs >= 0x80000000)
2633 | time_stamp->secs = (time_t)((int64_t)tmp64secs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2634 | else
2635 | time_stamp->secs = (time_t)((int64_t)tmp64secs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2636 | time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2637 | }
2638 | else {
2639 | time_stamp->secs = 0;
2640 | time_stamp->nsecs = 0;
2641 | report_type_length_mismatch(tree, "a time-in-milliseconds NTP time stamp", length, (length < 6));
2642 | }
2643 | break;
2644 |
2645 | case ENC_TIME_MP4_FILE_SECS0x00000026|ENC_BIG_ENDIAN0x00000000:
2646 | /*
2647 | * MP4 file time stamps, big-endian.
2648 | * Only supported for absolute times.
2649 | */
2650 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2650, "!is_relative" ))));
2651 |
2652 | if (length == 8) {
2653 | tmp64secs = tvb_get_ntoh64(tvb, start);
2654 | time_stamp->secs = (time_t)(int64_t)(tmp64secs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2655 | time_stamp->nsecs = 0;
2656 | } else if (length == 4) {
2657 | tmpsecs = tvb_get_ntohl(tvb, start);
2658 | time_stamp->secs = (time_t)(int32_t)(tmpsecs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2659 | time_stamp->nsecs = 0;
2660 | } else {
2661 | time_stamp->secs = 0;
2662 | time_stamp->nsecs = 0;
2663 | report_type_length_mismatch(tree, "an MP4 time stamp", length, (length < 4));
2664 | }
2665 | break;
2666 |
2667 | case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_BIG_ENDIAN0x00000000:
2668 | /*
2669 | * Zigbee ZCL time stamps, big-endian.
2670 | * Only supported for absolute times.
2671 | */
2672 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2672, "!is_relative" ))));
2673 |
2674 | if (length == 8) {
2675 | tmp64secs = tvb_get_ntoh64(tvb, start);
2676 | 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);
2677 | time_stamp->nsecs = 0;
2678 | } else if (length == 4) {
2679 | tmpsecs = tvb_get_ntohl(tvb, start);
2680 | time_stamp->secs = (time_t)(tmpsecs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2681 | time_stamp->nsecs = 0;
2682 | } else {
2683 | time_stamp->secs = 0;
2684 | time_stamp->nsecs = 0;
2685 | report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2686 | }
2687 | break;
2688 |
2689 | case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_LITTLE_ENDIAN0x80000000:
2690 | /*
2691 | * Zigbee ZCL time stamps, little-endian.
2692 | * Only supported for absolute times.
2693 | */
2694 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2694, "!is_relative" ))));
2695 |
2696 | if (length == 8) {
2697 | tmp64secs = tvb_get_letoh64(tvb, start);
2698 | 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);
2699 | time_stamp->nsecs = 0;
2700 | } else if (length == 4) {
2701 | tmpsecs = tvb_get_letohl(tvb, start);
2702 | time_stamp->secs = (time_t)(tmpsecs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2703 | time_stamp->nsecs = 0;
2704 | } else {
2705 | time_stamp->secs = 0;
2706 | time_stamp->nsecs = 0;
2707 | report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2708 | }
2709 | break;
2710 |
2711 | default:
2712 | DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\"" , "epan/proto.c", 2712));
2713 | break;
2714 | }
2715 | }
2716 |
2717 | static void
2718 | tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
2719 | {
2720 | const header_field_info *hfinfo = fi->hfinfo;
2721 |
2722 | if (hfinfo->ref_type == HF_REF_TYPE_DIRECT || hfinfo->ref_type == HF_REF_TYPE_PRINT) {
2723 | GPtrArray *ptrs = NULL((void*)0);
2724 |
2725 | if (tree_data->interesting_hfids == NULL((void*)0)) {
2726 | /* Initialize the hash because we now know that it is needed */
2727 | tree_data->interesting_hfids =
2728 | g_hash_table_new(g_direct_hash, NULL((void*)0) /* g_direct_equal */);
2729 | } else if (g_hash_table_size(tree_data->interesting_hfids)) {
2730 | ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
2731 | GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)));
2732 | }
2733 |
2734 | if (!ptrs) {
2735 | /* First element triggers the creation of pointer array */
2736 | ptrs = g_ptr_array_new();
2737 | g_hash_table_insert(tree_data->interesting_hfids,
2738 | GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)), ptrs);
2739 | }
2740 |
2741 | g_ptr_array_add(ptrs, fi);
2742 | }
2743 | }
2744 |
2745 |
2746 | /*
2747 | * Validates that field length bytes are available starting from
2748 | * start (pos/neg). Throws an exception if they aren't.
2749 | */
2750 | static void
2751 | test_length(header_field_info *hfinfo, tvbuff_t *tvb,
2752 | int start, int length, const unsigned encoding)
2753 | {
2754 | int size = length;
2755 |
2756 | if (!tvb)
2757 | return;
2758 |
2759 | if ((hfinfo->type == FT_STRINGZ) ||
2760 | ((encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) &&
2761 | (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 ))))) {
2762 | /* If we're fetching until the end of the TVB, only validate
2763 | * that the offset is within range.
2764 | */
2765 | if (length == -1)
2766 | size = 0;
2767 | }
2768 |
2769 | tvb_ensure_bytes_exist(tvb, start, size);
2770 | }
2771 |
2772 | static void
2773 | detect_trailing_stray_characters(unsigned encoding, const char *string, int length, proto_item *pi)
2774 | {
2775 | bool_Bool found_stray_character = false0;
2776 |
2777 | if (!string)
2778 | return;
2779 |
2780 | switch (encoding & ENC_CHARENCODING_MASK0x0000FFFE) {
2781 | case ENC_ASCII0x00000000:
2782 | case ENC_UTF_80x00000002:
2783 | for (int i = (int)strlen(string); i < length; i++) {
2784 | if (string[i] != '\0') {
2785 | found_stray_character = true1;
2786 | break;
2787 | }
2788 | }
2789 | break;
2790 |
2791 | default:
2792 | break;
2793 | }
2794 |
2795 | if (found_stray_character) {
2796 | expert_add_info(NULL((void*)0), pi, &ei_string_trailing_characters);
2797 | }
2798 | }
2799 |
2800 | static void
2801 | free_fvalue_cb(void *data)
2802 | {
2803 | fvalue_t *fv = (fvalue_t*)data;
2804 | fvalue_free(fv);
2805 | }
2806 |
2807 | /* Add an item to a proto_tree, using the text label registered to that item;
2808 | the item is extracted from the tvbuff handed to it. */
2809 | static proto_item *
2810 | proto_tree_new_item(field_info *new_fi, proto_tree *tree,
2811 | tvbuff_t *tvb, int start, int length,
2812 | unsigned encoding)
2813 | {
2814 | proto_item *pi;
2815 | uint32_t value, n;
2816 | uint64_t value64;
2817 | ws_in4_addr ipv4_value;
2818 | float floatval;
2819 | double doubleval;
2820 | const char *stringval = NULL((void*)0);
2821 | nstime_t time_stamp;
2822 | bool_Bool length_error;
2823 |
2824 | /* Ensure that the newly created fvalue_t is freed if we throw an
2825 | * exception before adding it to the tree. (gcc creates clobbering
2826 | * when it optimizes the equivalent TRY..EXCEPT implementation.)
2827 | * XXX: Move the new_field_info() call inside here?
2828 | */
2829 | 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));
2830 |
2831 | switch (new_fi->hfinfo->type) {
2832 | case FT_NONE:
2833 | /* no value to set for FT_NONE */
2834 | break;
2835 |
2836 | case FT_PROTOCOL:
2837 | proto_tree_set_protocol_tvb(new_fi, tvb, new_fi->hfinfo->name, length);
2838 | break;
2839 |
2840 | case FT_BYTES:
2841 | proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
2842 | break;
2843 |
2844 | case FT_UINT_BYTES:
2845 | n = get_uint_value(tree, tvb, start, length, encoding);
2846 | proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
2847 |
2848 | /* Instead of calling proto_item_set_len(), since we don't yet
2849 | * have a proto_item, we set the field_info's length ourselves. */
2850 | new_fi->length = n + length;
2851 | break;
2852 |
2853 | case FT_BOOLEAN:
2854 | /*
2855 | * Map all non-zero values to little-endian for
2856 | * backwards compatibility.
2857 | */
2858 | if (encoding)
2859 | encoding = ENC_LITTLE_ENDIAN0x80000000;
2860 | proto_tree_set_boolean(new_fi,
2861 | get_uint64_value(tree, tvb, start, length, encoding));
2862 | break;
2863 |
2864 | case FT_CHAR:
2865 | /* XXX - make these just FT_UINT? */
2866 | case FT_UINT8:
2867 | case FT_UINT16:
2868 | case FT_UINT24:
2869 | case FT_UINT32:
2870 | if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2871 | new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2872 | value = (uint32_t)value64;
2873 | if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2874 | new_fi->flags |= FI_VARINT0x00040000;
2875 | }
2876 | }
2877 | else {
2878 | /*
2879 | * Map all non-zero values to little-endian for
2880 | * backwards compatibility.
2881 | */
2882 | if (encoding)
2883 | encoding = ENC_LITTLE_ENDIAN0x80000000;
2884 |
2885 | value = get_uint_value(tree, tvb, start, length, encoding);
2886 | }
2887 | proto_tree_set_uint(new_fi, value);
2888 | break;
2889 |
2890 | case FT_UINT40:
2891 | case FT_UINT48:
2892 | case FT_UINT56:
2893 | case FT_UINT64:
2894 | if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2895 | new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2896 | if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2897 | new_fi->flags |= FI_VARINT0x00040000;
2898 | }
2899 | }
2900 | else {
2901 | /*
2902 | * Map all other non-zero values to little-endian for
2903 | * backwards compatibility.
2904 | */
2905 | if (encoding)
2906 | encoding = ENC_LITTLE_ENDIAN0x80000000;
2907 |
2908 | value64 = get_uint64_value(tree, tvb, start, length, encoding);
2909 | }
2910 | proto_tree_set_uint64(new_fi, value64);
2911 | break;
2912 |
2913 | /* XXX - make these just FT_INT? */
2914 | case FT_INT8:
2915 | case FT_INT16:
2916 | case FT_INT24:
2917 | case FT_INT32:
2918 | /*
2919 | * Map all non-zero values to little-endian for
2920 | * backwards compatibility.
2921 | */
2922 | if (encoding)
2923 | encoding = ENC_LITTLE_ENDIAN0x80000000;
2924 | proto_tree_set_int(new_fi,
2925 | get_int_value(tree, tvb, start, length, encoding));
2926 | break;
2927 |
2928 | case FT_INT40:
2929 | case FT_INT48:
2930 | case FT_INT56:
2931 | case FT_INT64:
2932 | /*
2933 | * Map all non-zero values to little-endian for
2934 | * backwards compatibility.
2935 | */
2936 | if (encoding)
2937 | encoding = ENC_LITTLE_ENDIAN0x80000000;
2938 | proto_tree_set_int64(new_fi,
2939 | get_int64_value(tree, tvb, start, length, encoding));
2940 | break;
2941 |
2942 | case FT_IPv4:
2943 | /*
2944 | * Map all non-zero values to little-endian for
2945 | * backwards compatibility.
2946 | */
2947 | if (encoding)
2948 | encoding = ENC_LITTLE_ENDIAN0x80000000;
2949 | if (length != FT_IPv4_LEN4) {
2950 | length_error = length < FT_IPv4_LEN4 ? true1 : false0;
2951 | report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
2952 | }
2953 | ipv4_value = tvb_get_ipv4(tvb, start);
2954 | /*
2955 | * NOTE: to support code written when
2956 | * proto_tree_add_item() took a bool as its
2957 | * last argument, with false meaning "big-endian"
2958 | * and true meaning "little-endian", we treat any
2959 | * non-zero value of "encoding" as meaning
2960 | * "little-endian".
2961 | */
2962 | 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);
2963 | break;
2964 |
2965 | case FT_IPXNET:
2966 | if (length != FT_IPXNET_LEN4) {
2967 | length_error = length < FT_IPXNET_LEN4 ? true1 : false0;
2968 | report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
2969 | }
2970 | proto_tree_set_ipxnet(new_fi,
2971 | get_uint_value(tree, tvb, start, FT_IPXNET_LEN4, ENC_BIG_ENDIAN0x00000000));
2972 | break;
2973 |
2974 | case FT_IPv6:
2975 | if (length != FT_IPv6_LEN16) {
2976 | length_error = length < FT_IPv6_LEN16 ? true1 : false0;
2977 | report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
2978 | }
2979 | proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
2980 | break;
2981 |
2982 | case FT_FCWWN:
2983 | if (length != FT_FCWWN_LEN8) {
2984 | length_error = length < FT_FCWWN_LEN8 ? true1 : false0;
2985 | report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
2986 | }
2987 | proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
2988 | break;
2989 |
2990 | case FT_AX25:
2991 | if (length != 7) {
2992 | length_error = length < 7 ? true1 : false0;
2993 | report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
2994 | }
2995 | proto_tree_set_ax25_tvb(new_fi, tvb, start);
2996 | break;
2997 |
2998 | case FT_VINES:
2999 | if (length != VINES_ADDR_LEN6) {
3000 | length_error = length < VINES_ADDR_LEN6 ? true1 : false0;
3001 | report_type_length_mismatch(tree, "a Vines address", length, length_error);
3002 | }
3003 | proto_tree_set_vines_tvb(new_fi, tvb, start);
3004 | break;
3005 |
3006 | case FT_ETHER:
3007 | if (length != FT_ETHER_LEN6) {
3008 | length_error = length < FT_ETHER_LEN6 ? true1 : false0;
3009 | report_type_length_mismatch(tree, "a MAC address", length, length_error);
3010 | }
3011 | proto_tree_set_ether_tvb(new_fi, tvb, start);
3012 | break;
3013 |
3014 | case FT_EUI64:
3015 | /*
3016 | * Map all non-zero values to little-endian for
3017 | * backwards compatibility.
3018 | */
3019 | if (encoding)
3020 | encoding = ENC_LITTLE_ENDIAN0x80000000;
3021 | if (length != FT_EUI64_LEN8) {
3022 | length_error = length < FT_EUI64_LEN8 ? true1 : false0;
3023 | report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
3024 | }
3025 | proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
3026 | break;
3027 | case FT_GUID:
3028 | /*
3029 | * Map all non-zero values to little-endian for
3030 | * backwards compatibility.
3031 | */
3032 | if (encoding)
3033 | encoding = ENC_LITTLE_ENDIAN0x80000000;
3034 | if (length != FT_GUID_LEN16) {
3035 | length_error = length < FT_GUID_LEN16 ? true1 : false0;
3036 | report_type_length_mismatch(tree, "a GUID", length, length_error);
3037 | }
3038 | proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
3039 | break;
3040 |
3041 | case FT_OID:
3042 | case FT_REL_OID:
3043 | proto_tree_set_oid_tvb(new_fi, tvb, start, length);
3044 | break;
3045 |
3046 | case FT_SYSTEM_ID:
3047 | proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
3048 | break;
3049 |
3050 | case FT_FLOAT:
3051 | /*
3052 | * NOTE: to support code written when
3053 | * proto_tree_add_item() took a bool as its
3054 | * last argument, with false meaning "big-endian"
3055 | * and true meaning "little-endian", we treat any
3056 | * non-zero value of "encoding" as meaning
3057 | * "little-endian".
3058 | *
3059 | * At some point in the future, we might
3060 | * support non-IEEE-binary floating-point
3061 | * formats in the encoding as well
3062 | * (IEEE decimal, System/3x0, VAX).
3063 | */
3064 | if (encoding)
3065 | encoding = ENC_LITTLE_ENDIAN0x80000000;
3066 | if (length != 4) {
3067 | length_error = length < 4 ? true1 : false0;
3068 | report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
3069 | }
3070 | if (encoding)
3071 | floatval = tvb_get_letohieee_float(tvb, start);
3072 | else
3073 | floatval = tvb_get_ntohieee_float(tvb, start);
3074 | proto_tree_set_float(new_fi, floatval);
3075 | break;
3076 |
3077 | case FT_DOUBLE:
3078 | /*
3079 | * NOTE: to support code written when
3080 | * proto_tree_add_item() took a bool as its
3081 | * last argument, with false meaning "big-endian"
3082 | * and true meaning "little-endian", we treat any
3083 | * non-zero value of "encoding" as meaning
3084 | * "little-endian".
3085 | *
3086 | * At some point in the future, we might
3087 | * support non-IEEE-binary floating-point
3088 | * formats in the encoding as well
3089 | * (IEEE decimal, System/3x0, VAX).
3090 | */
3091 | if (encoding == true1)
3092 | encoding = ENC_LITTLE_ENDIAN0x80000000;
3093 | if (length != 8) {
3094 | length_error = length < 8 ? true1 : false0;
3095 | report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
3096 | }
3097 | if (encoding)
3098 | doubleval = tvb_get_letohieee_double(tvb, start);
3099 | else
3100 | doubleval = tvb_get_ntohieee_double(tvb, start);
3101 | proto_tree_set_double(new_fi, doubleval);
3102 | break;
3103 |
3104 | case FT_STRING:
3105 | stringval = (const char*)get_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3106 | tvb, start, length, &length, encoding);
3107 | proto_tree_set_string(new_fi, stringval);
3108 |
3109 | /* Instead of calling proto_item_set_len(), since we
3110 | * don't yet have a proto_item, we set the
3111 | * field_info's length ourselves.
3112 | *
3113 | * XXX - our caller can't use that length to
3114 | * advance an offset unless they arrange that
3115 | * there always be a protocol tree into which
3116 | * we're putting this item.
3117 | */
3118 | new_fi->length = length;
3119 | break;
3120 |
3121 | case FT_STRINGZ:
3122 | stringval = (const char*)get_stringz_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3123 | tree, tvb, start, length, &length, encoding);
3124 | proto_tree_set_string(new_fi, stringval);
3125 |
3126 | /* Instead of calling proto_item_set_len(),
3127 | * since we don't yet have a proto_item, we
3128 | * set the field_info's length ourselves.
3129 | *
3130 | * XXX - our caller can't use that length to
3131 | * advance an offset unless they arrange that
3132 | * there always be a protocol tree into which
3133 | * we're putting this item.
3134 | */
3135 | new_fi->length = length;
3136 | break;
3137 |
3138 | case FT_UINT_STRING:
3139 | /*
3140 | * NOTE: to support code written when
3141 | * proto_tree_add_item() took a bool as its
3142 | * last argument, with false meaning "big-endian"
3143 | * and true meaning "little-endian", if the
3144 | * encoding value is true, treat that as
3145 | * ASCII with a little-endian length.
3146 | *
3147 | * This won't work for code that passes
3148 | * arbitrary non-zero values; that code
3149 | * will need to be fixed.
3150 | */
3151 | if (encoding == true1)
3152 | encoding = ENC_ASCII0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3153 | stringval = (const char*)get_uint_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3154 | tree, tvb, start, length, &length, encoding);
3155 | proto_tree_set_string(new_fi, stringval);
3156 |
3157 | /* Instead of calling proto_item_set_len(), since we
3158 | * don't yet have a proto_item, we set the
3159 | * field_info's length ourselves.
3160 | *
3161 | * XXX - our caller can't use that length to
3162 | * advance an offset unless they arrange that
3163 | * there always be a protocol tree into which
3164 | * we're putting this item.
3165 | */
3166 | new_fi->length = length;
3167 | break;
3168 |
3169 | case FT_STRINGZPAD:
3170 | stringval = (const char*)get_stringzpad_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3171 | tvb, start, length, &length, encoding);
3172 | proto_tree_set_string(new_fi, stringval);
3173 |
3174 | /* Instead of calling proto_item_set_len(), since we
3175 | * don't yet have a proto_item, we set the
3176 | * field_info's length ourselves.
3177 | *
3178 | * XXX - our caller can't use that length to
3179 | * advance an offset unless they arrange that
3180 | * there always be a protocol tree into which
3181 | * we're putting this item.
3182 | */
3183 | new_fi->length = length;
3184 | break;
3185 |
3186 | case FT_STRINGZTRUNC:
3187 | stringval = (const char*)get_stringztrunc_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3188 | tvb, start, length, &length, encoding);
3189 | proto_tree_set_string(new_fi, stringval);
3190 |
3191 | /* Instead of calling proto_item_set_len(), since we
3192 | * don't yet have a proto_item, we set the
3193 | * field_info's length ourselves.
3194 | *
3195 | * XXX - our caller can't use that length to
3196 | * advance an offset unless they arrange that
3197 | * there always be a protocol tree into which
3198 | * we're putting this item.
3199 | */
3200 | new_fi->length = length;
3201 | break;
3202 |
3203 | case FT_ABSOLUTE_TIME:
3204 | /*
3205 | * Absolute times can be in any of a number of
3206 | * formats, and they can be big-endian or
3207 | * little-endian.
3208 | *
3209 | * Historically FT_TIMEs were only timespecs;
3210 | * the only question was whether they were stored
3211 | * in big- or little-endian format.
3212 | *
3213 | * For backwards compatibility, we interpret an
3214 | * encoding of 1 as meaning "little-endian timespec",
3215 | * so that passing true is interpreted as that.
3216 | */
3217 | if (encoding == true1)
3218 | encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3219 |
3220 | get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
3221 |
3222 | proto_tree_set_time(new_fi, &time_stamp);
3223 | break;
3224 |
3225 | case FT_RELATIVE_TIME:
3226 | /*
3227 | * Relative times can be in any of a number of
3228 | * formats, and they can be big-endian or
3229 | * little-endian.
3230 | *
3231 | * Historically FT_TIMEs were only timespecs;
3232 | * the only question was whether they were stored
3233 | * in big- or little-endian format.
3234 | *
3235 | * For backwards compatibility, we interpret an
3236 | * encoding of 1 as meaning "little-endian timespec",
3237 | * so that passing true is interpreted as that.
3238 | */
3239 | if (encoding == true1)
3240 | encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3241 |
3242 | get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
3243 |
3244 | proto_tree_set_time(new_fi, &time_stamp);
3245 | break;
3246 | case FT_IEEE_11073_SFLOAT:
3247 | if (encoding)
3248 | encoding = ENC_LITTLE_ENDIAN0x80000000;
3249 | if (length != 2) {
3250 | length_error = length < 2 ? true1 : false0;
3251 | report_type_length_mismatch(tree, "a IEEE 11073 SFLOAT", length, length_error);
3252 | }
3253 |
3254 | fvalue_set_uinteger(new_fi->value, tvb_get_uint16(tvb, start, encoding));
3255 |
3256 | break;
3257 | case FT_IEEE_11073_FLOAT:
3258 | if (encoding)
3259 | encoding = ENC_LITTLE_ENDIAN0x80000000;
3260 | if (length != 4) {
3261 | length_error = length < 4 ? true1 : false0;
3262 | report_type_length_mismatch(tree, "a IEEE 11073 FLOAT", length, length_error);
3263 | }
3264 | fvalue_set_uinteger(new_fi->value, tvb_get_uint32(tvb, start, encoding));
3265 |
3266 | break;
3267 | default:
3268 | 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))
3269 | 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))
3270 | 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))
3271 | 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));
3272 | break;
3273 | }
3274 | 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);
3275 |
3276 | /* Don't add new node to proto_tree until now so that any exceptions
3277 | * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
3278 | /* XXX. wouldn't be better to add this item to tree, with some special
3279 | * flag (FI_EXCEPTION?) to know which item caused exception? For
3280 | * strings and bytes, we would have to set new_fi->value to something
3281 | * non-NULL, or otherwise ensure that proto_item_fill_display_label
3282 | * could handle NULL values. */
3283 | CLEANUP_POPexcept_pop(); if (0) except_cl.except_func(except_cl.except_context ); }
3284 | pi = proto_tree_add_node(tree, new_fi);
3285 |
3286 | switch (new_fi->hfinfo->type) {
3287 |
3288 | case FT_STRING:
3289 | /* XXX: trailing stray character detection should be done
3290 | * _before_ conversion to UTF-8, because conversion can change
3291 | * the length, or else get_string_length should return a value
3292 | * for the "length in bytes of the string after conversion
3293 | * including internal nulls." (Noting that we do, for other
3294 | * reasons, still need the "length in bytes in the field",
3295 | * especially for FT_STRINGZ.)
3296 | *
3297 | * This is true even for ASCII and UTF-8, because
3298 | * substituting REPLACEMENT CHARACTERS for illegal characters
3299 | * can also do so (and for UTF-8 possibly even make the
3300 | * string _shorter_).
3301 | */
3302 | detect_trailing_stray_characters(encoding, stringval, length, pi);
3303 | break;
3304 |
3305 | default:
3306 | break;
3307 | }
3308 |
3309 | return pi;
3310 | }
3311 |
3312 | proto_item *
3313 | proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3314 | const int start, int length,
3315 | const unsigned encoding, int32_t *retval)
3316 | {
3317 | header_field_info *hfinfo;
3318 | field_info *new_fi;
3319 | int32_t value;
3320 |
3321 | 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", 3321, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3321, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3321, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3322 |
3323 | switch (hfinfo->type) {
3324 | case FT_INT8:
3325 | case FT_INT16:
3326 | case FT_INT24:
3327 | case FT_INT32:
3328 | break;
3329 | case FT_INT64:
3330 | 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)
3331 | hfinfo->abbrev)proto_report_dissector_bug("64-bit signed integer field %s used with proto_tree_add_item_ret_int()" , hfinfo->abbrev);
3332 | default:
3333 | 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)
3334 | hfinfo->abbrev)proto_report_dissector_bug("Non-signed-integer field %s used with proto_tree_add_item_ret_int()" , hfinfo->abbrev);
3335 | }
3336 |
3337 | CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3338 | {if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3339 | if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3340 | {if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3341 | *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3342 | }if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3343 | } )if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); };
3344 |
3345 | if (encoding & ENC_STRING0x03000000) {
3346 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3347 | }
3348 | /* I believe it's ok if this is called with a NULL tree */
3349 | value = get_int_value(tree, tvb, start, length, encoding);
3350 |
3351 | if (retval) {
3352 | int no_of_bits;
3353 | *retval = value;
3354 | if (hfinfo->bitmask) {
3355 | /* Mask out irrelevant portions */
3356 | *retval &= (uint32_t)(hfinfo->bitmask);
3357 | /* Shift bits */
3358 | *retval >>= hfinfo_bitshift(hfinfo);
3359 | }
3360 | no_of_bits = ws_count_ones(hfinfo->bitmask);
3361 | *retval = ws_sign_ext32(*retval, no_of_bits);
3362 | }
3363 |
3364 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3365 |
3366 | 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", 3366 , __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", 3366, "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", 3366, "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", 3366, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
3367 |
3368 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3369 |
3370 | proto_tree_set_int(new_fi, value);
3371 |
3372 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3373 |
3374 | return proto_tree_add_node(tree, new_fi);
3375 | }
3376 |
3377 | proto_item *
3378 | proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3379 | const int start, int length,
3380 | const unsigned encoding, uint32_t *retval)
3381 | {
3382 | header_field_info *hfinfo;
3383 | field_info *new_fi;
3384 | uint32_t value;
3385 |
3386 | 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", 3386, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3386, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3386, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3387 |
3388 | switch (hfinfo->type) {
3389 | case FT_CHAR:
3390 | case FT_UINT8:
3391 | case FT_UINT16:
3392 | case FT_UINT24:
3393 | case FT_UINT32:
3394 | break;
3395 | default:
3396 | 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)
3397 | 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);
3398 | }
3399 |
3400 | CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3401 | {if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3402 | if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3403 | {if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3404 | *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3405 | }if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3406 | } )if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); };
3407 |
3408 | if (encoding & ENC_STRING0x03000000) {
3409 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3410 | }
3411 | /* I believe it's ok if this is called with a NULL tree */
3412 | /* XXX - modify if we ever support EBCDIC FT_CHAR */
3413 | if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3414 | uint64_t temp64;
3415 | tvb_get_varint(tvb, start, length, &temp64, encoding);
3416 | value = (uint32_t)temp64;
3417 | } else {
3418 | value = get_uint_value(tree, tvb, start, length, encoding);
3419 | }
3420 |
3421 | if (retval) {
3422 | *retval = value;
3423 | if (hfinfo->bitmask) {
3424 | /* Mask out irrelevant portions */
3425 | *retval &= (uint32_t)(hfinfo->bitmask);
3426 | /* Shift bits */
3427 | *retval >>= hfinfo_bitshift(hfinfo);
3428 | }
3429 | }
3430 |
3431 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3432 |
3433 | 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", 3433 , __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", 3433, "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", 3433, "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", 3433, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
3434 |
3435 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3436 |
3437 | proto_tree_set_uint(new_fi, value);
3438 |
3439 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3440 | if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3441 | new_fi->flags |= FI_VARINT0x00040000;
3442 | }
3443 | return proto_tree_add_node(tree, new_fi);
3444 | }
3445 |
3446 | /* Gets data from tvbuff, adds it to proto_tree, increments offset,
3447 | * and returns proto_item* and uint value retrieved*/
3448 | proto_item *
3449 | ptvcursor_add_ret_uint(ptvcursor_t *ptvc, int hfindex, int length,
3450 | const unsigned encoding, uint32_t *retval)
3451 | {
3452 | field_info *new_fi;
3453 | header_field_info *hfinfo;
3454 | int item_length;
3455 | int offset;
3456 | uint32_t value;
3457 |
3458 | offset = ptvc->offset;
3459 | 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", 3459, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3459, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3459, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3460 |
3461 | switch (hfinfo->type) {
3462 | case FT_CHAR:
3463 | case FT_UINT8:
3464 | case FT_UINT16:
3465 | case FT_UINT24:
3466 | case FT_UINT32:
3467 | break;
3468 | default:
3469 | 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)
3470 | 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);
3471 | }
3472 |
3473 | get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3474 | test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3475 |
3476 | /* I believe it's ok if this is called with a NULL tree */
3477 | /* XXX - modify if we ever support EBCDIC FT_CHAR */
3478 | value = get_uint_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3479 |
3480 | if (retval) {
3481 | *retval = value;
3482 | if (hfinfo->bitmask) {
3483 | /* Mask out irrelevant portions */
3484 | *retval &= (uint32_t)(hfinfo->bitmask);
3485 | /* Shift bits */
3486 | *retval >>= hfinfo_bitshift(hfinfo);
3487 | }
3488 | }
3489 |
3490 | ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3491 |
3492 | CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3493 |
3494 | /* Coast clear. Try and fake it */
3495 | 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", 3495 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3495, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3495, "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", 3495, __func__, "Adding %s would put more than %d 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); } } };
3496 |
3497 | new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3498 |
3499 | return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3500 | offset, length, encoding);
3501 | }
3502 |
3503 | /* Gets data from tvbuff, adds it to proto_tree, increments offset,
3504 | * and returns proto_item* and int value retrieved*/
3505 | proto_item *
3506 | ptvcursor_add_ret_int(ptvcursor_t *ptvc, int hfindex, int length,
3507 | const unsigned encoding, int32_t *retval)
3508 | {
3509 | field_info *new_fi;
3510 | header_field_info *hfinfo;
3511 | int item_length;
3512 | int offset;
3513 | uint32_t value;
3514 |
3515 | offset = ptvc->offset;
3516 | 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", 3516, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3516, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3516, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3517 |
3518 | switch (hfinfo->type) {
3519 | case FT_INT8:
3520 | case FT_INT16:
3521 | case FT_INT24:
3522 | case FT_INT32:
3523 | break;
3524 | default:
3525 | 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)
3526 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32" , hfinfo->abbrev);
3527 | }
3528 |
3529 | get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3530 | test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3531 |
3532 | /* I believe it's ok if this is called with a NULL tree */
3533 | /* XXX - modify if we ever support EBCDIC FT_CHAR */
3534 | value = get_int_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3535 |
3536 | if (retval) {
3537 | int no_of_bits;
3538 | *retval = value;
3539 | if (hfinfo->bitmask) {
3540 | /* Mask out irrelevant portions */
3541 | *retval &= (uint32_t)(hfinfo->bitmask);
3542 | /* Shift bits */
3543 | *retval >>= hfinfo_bitshift(hfinfo);
3544 | }
3545 | no_of_bits = ws_count_ones(hfinfo->bitmask);
3546 | *retval = ws_sign_ext32(*retval, no_of_bits);
3547 | }
3548 |
3549 | ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3550 |
3551 | CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3552 |
3553 | /* Coast clear. Try and fake it */
3554 | 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", 3554 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3554, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3554, "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", 3554, __func__, "Adding %s would put more than %d 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); } } };
3555 |
3556 | new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3557 |
3558 | return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3559 | offset, length, encoding);
3560 | }
3561 |
3562 | /* Gets data from tvbuff, adds it to proto_tree, increments offset,
3563 | * and returns proto_item* and string value retrieved */
3564 | proto_item*
3565 | ptvcursor_add_ret_string(ptvcursor_t* ptvc, int hf, int length, const unsigned encoding, wmem_allocator_t *scope, const uint8_t **retval)
3566 | {
3567 | header_field_info *hfinfo;
3568 | field_info *new_fi;
3569 | const uint8_t *value;
3570 | int item_length;
3571 | int offset;
3572 |
3573 | offset = ptvc->offset;
3574 |
3575 | 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", 3575 , __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", 3575, "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", 3575, "gpa_hfinfo.hfi[hf] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[hf];;
3576 |
3577 | switch (hfinfo->type) {
3578 | case FT_STRING:
3579 | value = get_string_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3580 | break;
3581 | case FT_STRINGZ:
3582 | value = get_stringz_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3583 | break;
3584 | case FT_UINT_STRING:
3585 | value = get_uint_string_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3586 | break;
3587 | case FT_STRINGZPAD:
3588 | value = get_stringzpad_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3589 | break;
3590 | case FT_STRINGZTRUNC:
3591 | value = get_stringztrunc_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3592 | break;
3593 | default:
3594 | 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)
3595 | 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);
3596 | }
3597 |
3598 | if (retval)
3599 | *retval = value;
3600 |
3601 | ptvcursor_advance(ptvc, item_length);
3602 |
3603 | CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3604 |
3605 | 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", 3605, __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", 3605, "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", 3605, "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", 3605 , __func__, "Adding %s would put more than %d 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); } } };
3606 |
3607 | new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3608 |
3609 | return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3610 | offset, length, encoding);
3611 | }
3612 |
3613 | /* Gets data from tvbuff, adds it to proto_tree, increments offset,
3614 | * and returns proto_item* and boolean value retrieved */
3615 | proto_item*
3616 | ptvcursor_add_ret_boolean(ptvcursor_t* ptvc, int hfindex, int length, const unsigned encoding, bool_Bool *retval)
3617 | {
3618 | header_field_info *hfinfo;
3619 | field_info *new_fi;
3620 | int item_length;
3621 | int offset;
3622 | uint64_t value, bitval;
3623 |
3624 | offset = ptvc->offset;
3625 | 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", 3625, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3625, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3625, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3626 |
3627 | if (hfinfo->type != FT_BOOLEAN) {
3628 | 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)
3629 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN" , hfinfo->abbrev);
3630 | }
3631 |
3632 | CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3633 | {if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3634 | if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3635 | {if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3636 | *retval = false;if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3637 | }if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3638 | } )if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); };
3639 |
3640 | if (encoding & ENC_STRING0x03000000) {
3641 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3642 | }
3643 |
3644 | get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3645 | test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3646 |
3647 | /* I believe it's ok if this is called with a NULL tree */
3648 | value = get_uint64_value(ptvc->tree, ptvc->tvb, offset, length, encoding);
3649 |
3650 | if (retval) {
3651 | bitval = value;
3652 | if (hfinfo->bitmask) {
3653 | /* Mask out irrelevant portions */
3654 | bitval &= hfinfo->bitmask;
3655 | }
3656 | *retval = (bitval != 0);
3657 | }
3658 |
3659 | ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3660 |
3661 | CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3662 |
3663 | 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", 3663, __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", 3663, "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", 3663, "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", 3663 , __func__, "Adding %s would put more than %d 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); } } };
3664 |
3665 | new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3666 |
3667 | return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3668 | offset, length, encoding);
3669 | }
3670 |
3671 | proto_item *
3672 | proto_tree_add_item_ret_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3673 | const int start, int length, const unsigned encoding, uint64_t *retval)
3674 | {
3675 | header_field_info *hfinfo;
3676 | field_info *new_fi;
3677 | uint64_t value;
3678 |
3679 | 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", 3679, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3679, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3679, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3680 |
3681 | switch (hfinfo->type) {
3682 | case FT_UINT40:
3683 | case FT_UINT48:
3684 | case FT_UINT56:
3685 | case FT_UINT64:
3686 | break;
3687 | default:
3688 | 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)
3689 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64" , hfinfo->abbrev);
3690 | }
3691 |
3692 | CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3693 | {if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3694 | if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3695 | {if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3696 | *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3697 | }if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3698 | } )if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); };
3699 |
3700 | if (encoding & ENC_STRING0x03000000) {
3701 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3702 | }
3703 | /* I believe it's ok if this is called with a NULL tree */
3704 | if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3705 | tvb_get_varint(tvb, start, length, &value, encoding);
3706 | } else {
3707 | value = get_uint64_value(tree, tvb, start, length, encoding);
3708 | }
3709 |
3710 | if (retval) {
3711 | *retval = value;
3712 | if (hfinfo->bitmask) {
3713 | /* Mask out irrelevant portions */
3714 | *retval &= hfinfo->bitmask;
3715 | /* Shift bits */
3716 | *retval >>= hfinfo_bitshift(hfinfo);
3717 | }
3718 | }
3719 |
3720 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3721 |
3722 | 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", 3722 , __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", 3722, "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", 3722, "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", 3722, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
3723 |
3724 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3725 |
3726 | proto_tree_set_uint64(new_fi, value);
3727 |
3728 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3729 | if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3730 | new_fi->flags |= FI_VARINT0x00040000;
3731 | }
3732 |
3733 | return proto_tree_add_node(tree, new_fi);
3734 | }
3735 |
3736 | proto_item *
3737 | proto_tree_add_item_ret_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3738 | const int start, int length, const unsigned encoding, int64_t *retval)
3739 | {
3740 | header_field_info *hfinfo;
3741 | field_info *new_fi;
3742 | int64_t value;
3743 |
3744 | 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", 3744, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3744, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3744, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3745 |
3746 | switch (hfinfo->type) {
3747 | case FT_INT40:
3748 | case FT_INT48:
3749 | case FT_INT56:
3750 | case FT_INT64:
3751 | break;
3752 | default:
3753 | 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)
3754 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64" , hfinfo->abbrev);
3755 | }
3756 |
3757 | CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3758 | {if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3759 | if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3760 | {if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3761 | *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3762 | }if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3763 | } )if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); };
3764 |
3765 | if (encoding & ENC_STRING0x03000000) {
3766 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3767 | }
3768 | /* I believe it's ok if this is called with a NULL tree */
3769 | if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3770 | tvb_get_varint(tvb, start, length, (uint64_t*)&value, encoding);
3771 | }
3772 | else {
3773 | value = get_int64_value(tree, tvb, start, length, encoding);
3774 | }
3775 |
3776 | if (retval) {
3777 | *retval = value;
3778 | }
3779 |
3780 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3781 |
3782 | 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", 3782 , __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", 3782, "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", 3782, "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", 3782, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
3783 |
3784 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3785 |
3786 | proto_tree_set_int64(new_fi, value);
3787 |
3788 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3789 | if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3790 | new_fi->flags |= FI_VARINT0x00040000;
3791 | }
3792 |
3793 | return proto_tree_add_node(tree, new_fi);
3794 | }
3795 |
3796 | proto_item *
3797 | proto_tree_add_item_ret_varint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3798 | const int start, int length, const unsigned encoding, uint64_t *retval, int *lenretval)
3799 | {
3800 | header_field_info *hfinfo;
3801 | field_info *new_fi;
3802 | uint64_t value;
3803 |
3804 | 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", 3804, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3804, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3804, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3805 |
3806 | 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 )))) {
3807 | 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)
3808 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT or FT_INT" , hfinfo->abbrev);
3809 | }
3810 |
3811 | /* length validation for native number encoding caught by get_uint64_value() */
3812 | /* length has to be -1 or > 0 regardless of encoding */
3813 | if (length == 0)
3814 | 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)
3815 | length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_varint" , length);
3816 |
3817 | if (encoding & ENC_STRING0x03000000) {
3818 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3819 | }
3820 |
3821 | length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value, encoding);
3822 |
3823 | if (retval) {
3824 | *retval = value;
3825 | if (hfinfo->bitmask) {
3826 | /* Mask out irrelevant portions */
3827 | *retval &= hfinfo->bitmask;
3828 | /* Shift bits */
3829 | *retval >>= hfinfo_bitshift(hfinfo);
3830 | }
3831 | }
3832 |
3833 | if (lenretval) {
3834 | *lenretval = length;
3835 | }
3836 |
3837 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3838 |
3839 | 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", 3839 , __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", 3839, "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", 3839, "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", 3839, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
3840 |
3841 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3842 |
3843 | proto_tree_set_uint64(new_fi, value);
3844 |
3845 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3846 | if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3847 | new_fi->flags |= FI_VARINT0x00040000;
3848 | }
3849 |
3850 | return proto_tree_add_node(tree, new_fi);
3851 |
3852 | }
3853 |
3854 | proto_item *
3855 | proto_tree_add_item_ret_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3856 | const int start, int length,
3857 | const unsigned encoding, bool_Bool *retval)
3858 | {
3859 | header_field_info *hfinfo;
3860 | field_info *new_fi;
3861 | uint64_t value, bitval;
3862 |
3863 | 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", 3863, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3863, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3863, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3864 |
3865 | if (hfinfo->type != FT_BOOLEAN) {
3866 | 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)
3867 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN" , hfinfo->abbrev);
3868 | }
3869 |
3870 | CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3871 | {if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3872 | if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3873 | {if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3874 | *retval = false;if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3875 | }if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3876 | } )if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); };
3877 |
3878 | if (encoding & ENC_STRING0x03000000) {
3879 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3880 | }
3881 | /* I believe it's ok if this is called with a NULL tree */
3882 | value = get_uint64_value(tree, tvb, start, length, encoding);
3883 |
3884 | if (retval) {
3885 | bitval = value;
3886 | if (hfinfo->bitmask) {
3887 | /* Mask out irrelevant portions */
3888 | bitval &= hfinfo->bitmask;
3889 | }
3890 | *retval = (bitval != 0);
3891 | }
3892 |
3893 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3894 |
3895 | 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", 3895 , __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", 3895, "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", 3895, "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", 3895, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
3896 |
3897 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3898 |
3899 | proto_tree_set_boolean(new_fi, value);
3900 |
3901 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3902 |
3903 | return proto_tree_add_node(tree, new_fi);
3904 | }
3905 |
3906 | proto_item *
3907 | proto_tree_add_item_ret_float(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3908 | const int start, int length,
3909 | const unsigned encoding, float *retval)
3910 | {
3911 | header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3912 | field_info *new_fi;
3913 | float value;
3914 |
3915 | 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", 3915, "hfinfo != ((void*)0)", "Not passed hfi!"))));
3916 |
3917 | if (hfinfo->type != FT_FLOAT) {
3918 | 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);
3919 | }
3920 |
3921 | if (length != 4) {
3922 | report_type_length_mismatch(tree, "a single-precision floating point number", length, true1);
3923 | }
3924 |
3925 | /* treat any nonzero encoding as little endian for backwards compatibility */
3926 | value = encoding ? tvb_get_letohieee_float(tvb, start) : tvb_get_ntohieee_float(tvb, start);
3927 | if (retval) {
3928 | *retval = value;
3929 | }
3930 |
3931 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3932 |
3933 | 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", 3933 , __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", 3933, "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", 3933, "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", 3933, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
3934 |
3935 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3936 | if (encoding) {
3937 | new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
3938 | }
3939 |
3940 | proto_tree_set_float(new_fi, value);
3941 |
3942 | return proto_tree_add_node(tree, new_fi);
3943 | }
3944 |
3945 | proto_item *
3946 | proto_tree_add_item_ret_double(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3947 | const int start, int length,
3948 | const unsigned encoding, double *retval)
3949 | {
3950 | header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3951 | field_info *new_fi;
3952 | double value;
3953 |
3954 | 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", 3954, "hfinfo != ((void*)0)", "Not passed hfi!"))));
3955 |
3956 | if (hfinfo->type != FT_DOUBLE) {
3957 | 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);
3958 | }
3959 |
3960 | if (length != 8) {
3961 | report_type_length_mismatch(tree, "a double-precision floating point number", length, true1);
3962 | }
3963 |
3964 | /* treat any nonzero encoding as little endian for backwards compatibility */
3965 | value = encoding ? tvb_get_letohieee_double(tvb, start) : tvb_get_ntohieee_double(tvb, start);
3966 | if (retval) {
3967 | *retval = value;
3968 | }
3969 |
3970 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3971 |
3972 | 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", 3972 , __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", 3972, "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", 3972, "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", 3972, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
3973 |
3974 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3975 | if (encoding) {
3976 | new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
3977 | }
3978 |
3979 | proto_tree_set_double(new_fi, value);
3980 |
3981 | return proto_tree_add_node(tree, new_fi);
3982 | }
3983 |
3984 | proto_item *
3985 | proto_tree_add_item_ret_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3986 | const int start, int length,
3987 | const unsigned encoding, ws_in4_addr *retval)
3988 | {
3989 | header_field_info *hfinfo;
3990 | field_info *new_fi;
3991 | ws_in4_addr value;
3992 |
3993 | 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", 3993, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3993, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3993, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3994 |
3995 | switch (hfinfo->type) {
3996 | case FT_IPv4:
3997 | break;
3998 | default:
3999 | 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)
4000 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv4", hfinfo->abbrev);
4001 | }
4002 |
4003 | if (length != FT_IPv4_LEN4)
4004 | 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)
4005 | length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv4" , length);
4006 |
4007 | if (encoding & (ENC_STRING0x03000000 | ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010))) {
4008 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
4009 | }
4010 |
4011 | /*
4012 | * NOTE: to support code written when proto_tree_add_item() took
4013 | * a bool as its last argument, with false meaning "big-endian"
4014 | * and true meaning "little-endian", we treat any non-zero value
4015 | * of "encoding" as meaning "little-endian".
4016 | */
4017 | value = tvb_get_ipv4(tvb, start);
4018 | if (encoding)
4019 | 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))));
4020 |
4021 | if (retval) {
4022 | *retval = value;
4023 | }
4024 |
4025 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4026 |
4027 | 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", 4027 , __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", 4027, "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", 4027, "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", 4027, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4028 |
4029 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4030 |
4031 | proto_tree_set_ipv4(new_fi, value);
4032 |
4033 | new_fi->flags |= encoding ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4034 | return proto_tree_add_node(tree, new_fi);
4035 | }
4036 |
4037 | proto_item *
4038 | proto_tree_add_item_ret_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4039 | const int start, int length,
4040 | const unsigned encoding, ws_in6_addr *addr)
4041 | {
4042 | header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4043 | field_info *new_fi;
4044 |
4045 | 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", 4045, "hfinfo != ((void*)0)", "Not passed hfi!"))));
4046 |
4047 | switch (hfinfo->type) {
4048 | case FT_IPv6:
4049 | break;
4050 | default:
4051 | 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)
4052 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv6", hfinfo->abbrev);
4053 | }
4054 |
4055 | if (length != FT_IPv6_LEN16)
4056 | 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)
4057 | length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv6" , length);
4058 |
4059 | if (encoding) {
4060 | 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" );
4061 | }
4062 |
4063 | tvb_get_ipv6(tvb, start, addr);
4064 |
4065 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4066 |
4067 | 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", 4067 , __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", 4067, "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", 4067, "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", 4067, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4068 |
4069 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4070 |
4071 | proto_tree_set_ipv6(new_fi, addr);
4072 |
4073 | return proto_tree_add_node(tree, new_fi);
4074 | }
4075 |
4076 | proto_item *
4077 | proto_tree_add_item_ret_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4078 | const int start, int length, const unsigned encoding, uint8_t *retval) {
4079 |
4080 | header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4081 | field_info *new_fi;
4082 |
4083 | 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", 4083, "hfinfo != ((void*)0)", "Not passed hfi!"))));
4084 |
4085 | switch (hfinfo->type) {
4086 | case FT_ETHER:
4087 | break;
4088 | default:
4089 | 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)
4090 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ETHER" , hfinfo->abbrev);
4091 | }
4092 |
4093 | if (length != FT_ETHER_LEN6)
4094 | 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)
4095 | length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ether" , length);
4096 |
4097 | if (encoding) {
4098 | 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" );
4099 | }
4100 |
4101 | tvb_memcpy(tvb, retval, start, length);
4102 |
4103 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4104 |
4105 | 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", 4105 , __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", 4105, "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", 4105, "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", 4105, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4106 |
4107 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4108 |
4109 | proto_tree_set_ether(new_fi, retval);
4110 |
4111 | return proto_tree_add_node(tree, new_fi);
4112 | }
4113 |
4114 |
4115 | proto_item *
4116 | proto_tree_add_item_ret_string_and_length(proto_tree *tree, int hfindex,
4117 | tvbuff_t *tvb,
4118 | const int start, int length,
4119 | const unsigned encoding,
4120 | wmem_allocator_t *scope,
4121 | const uint8_t **retval,
4122 | int *lenretval)
4123 | {
4124 | proto_item *pi;
4125 | header_field_info *hfinfo;
4126 | field_info *new_fi;
4127 | const uint8_t *value;
4128 |
4129 | 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", 4129, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4129, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4129, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4130 |
4131 | switch (hfinfo->type) {
4132 | case FT_STRING:
4133 | value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4134 | break;
4135 | case FT_STRINGZ:
4136 | value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4137 | break;
4138 | case FT_UINT_STRING:
4139 | value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4140 | break;
4141 | case FT_STRINGZPAD:
4142 | value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4143 | break;
4144 | case FT_STRINGZTRUNC:
4145 | value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4146 | break;
4147 | default:
4148 | 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)
4149 | 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);
4150 | }
4151 |
4152 | if (retval)
4153 | *retval = value;
4154 |
4155 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4156 |
4157 | 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", 4157 , __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", 4157, "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", 4157, "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", 4157, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4158 |
4159 | new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4160 |
4161 | proto_tree_set_string(new_fi, (const char*)value);
4162 |
4163 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4164 |
4165 | pi = proto_tree_add_node(tree, new_fi);
4166 |
4167 | switch (hfinfo->type) {
4168 |
4169 | case FT_STRINGZ:
4170 | case FT_STRINGZPAD:
4171 | case FT_STRINGZTRUNC:
4172 | case FT_UINT_STRING:
4173 | break;
4174 |
4175 | case FT_STRING:
4176 | detect_trailing_stray_characters(encoding, (const char*)value, length, pi);
4177 | break;
4178 |
4179 | default:
4180 | ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4180 , __func__, "assertion \"not reached\" failed");
4181 | }
4182 |
4183 | return pi;
4184 | }
4185 |
4186 | proto_item *
4187 | proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4188 | const int start, int length,
4189 | const unsigned encoding, wmem_allocator_t *scope,
4190 | const uint8_t **retval)
4191 | {
4192 | return proto_tree_add_item_ret_string_and_length(tree, hfindex,
4193 | tvb, start, length, encoding, scope, retval, &length);
4194 | }
4195 |
4196 | proto_item *
4197 | proto_tree_add_item_ret_display_string_and_length(proto_tree *tree, int hfindex,
4198 | tvbuff_t *tvb,
4199 | const int start, int length,
4200 | const unsigned encoding,
4201 | wmem_allocator_t *scope,
4202 | char **retval,
4203 | int *lenretval)
4204 | {
4205 | proto_item *pi;
4206 | header_field_info *hfinfo;
4207 | field_info *new_fi;
4208 | const uint8_t *value;
4209 | uint32_t n = 0;
4210 |
4211 | 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", 4211, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4211, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4211, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4212 |
4213 | switch (hfinfo->type) {
4214 | case FT_STRING:
4215 | value = get_string_value(scope, 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_STRINGZ:
4220 | value = get_stringz_value(scope, tree, 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_UINT_STRING:
4225 | value = get_uint_string_value(scope, tree, 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_STRINGZPAD:
4230 | value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4231 | *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4232 | ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4233 | break;
4234 | case FT_STRINGZTRUNC:
4235 | value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4236 | *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4237 | ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4238 | break;
4239 | case FT_BYTES:
4240 | tvb_ensure_bytes_exist(tvb, start, length);
4241 | value = tvb_get_ptr(tvb, start, length);
4242 | *retval = format_bytes_hfinfo(scope, hfinfo, value, length);
4243 | *lenretval = length;
4244 | break;
4245 | case FT_UINT_BYTES:
4246 | n = get_uint_value(tree, tvb, start, length, encoding);
4247 | tvb_ensure_bytes_exist(tvb, start + length, n);
4248 | value = tvb_get_ptr(tvb, start + length, n);
4249 | *retval = format_bytes_hfinfo(scope, hfinfo, value, n);
4250 | *lenretval = length + n;
4251 | break;
4252 | default:
4253 | 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)
4254 | 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);
4255 | }
4256 |
4257 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4258 |
4259 | 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", 4259 , __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", 4259, "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", 4259, "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", 4259, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4260 |
4261 | new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4262 |
4263 | switch (hfinfo->type) {
4264 |
4265 | case FT_STRING:
4266 | case FT_STRINGZ:
4267 | case FT_UINT_STRING:
4268 | case FT_STRINGZPAD:
4269 | case FT_STRINGZTRUNC:
4270 | proto_tree_set_string(new_fi, (const char*)value);
4271 | break;
4272 |
4273 | case FT_BYTES:
4274 | proto_tree_set_bytes(new_fi, value, length);
4275 | break;
4276 |
4277 | case FT_UINT_BYTES:
4278 | proto_tree_set_bytes(new_fi, value, n);
4279 | break;
4280 |
4281 | default:
4282 | ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4282 , __func__, "assertion \"not reached\" failed");
4283 | }
4284 |
4285 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4286 |
4287 | pi = proto_tree_add_node(tree, new_fi);
4288 |
4289 | switch (hfinfo->type) {
4290 |
4291 | case FT_STRINGZ:
4292 | case FT_STRINGZPAD:
4293 | case FT_STRINGZTRUNC:
4294 | case FT_UINT_STRING:
4295 | break;
4296 |
4297 | case FT_STRING:
4298 | detect_trailing_stray_characters(encoding, (const char*)value, length, pi);
4299 | break;
4300 |
4301 | case FT_BYTES:
4302 | case FT_UINT_BYTES:
4303 | break;
4304 |
4305 | default:
4306 | ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4306 , __func__, "assertion \"not reached\" failed");
4307 | }
4308 |
4309 | return pi;
4310 | }
4311 |
4312 | proto_item *
4313 | proto_tree_add_item_ret_display_string(proto_tree *tree, int hfindex,
4314 | tvbuff_t *tvb,
4315 | const int start, int length,
4316 | const unsigned encoding,
4317 | wmem_allocator_t *scope,
4318 | char **retval)
4319 | {
4320 | return proto_tree_add_item_ret_display_string_and_length(tree, hfindex,
4321 | tvb, start, length, encoding, scope, retval, &length);
4322 | }
4323 |
4324 | proto_item *
4325 | proto_tree_add_item_ret_time_string(proto_tree *tree, int hfindex,
4326 | tvbuff_t *tvb,
4327 | const int start, int length, const unsigned encoding,
4328 | wmem_allocator_t *scope, char **retval)
4329 | {
4330 | header_field_info *hfinfo;
4331 | field_info *new_fi;
4332 | nstime_t time_stamp;
4333 | int flags;
4334 |
4335 | 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", 4335, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4335, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4335, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4336 |
4337 | switch (hfinfo->type) {
4338 | case FT_ABSOLUTE_TIME:
4339 | get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
4340 | flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
4341 | if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
4342 | flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
4343 | }
4344 | *retval = abs_time_to_str_ex(scope, &time_stamp, hfinfo->display, flags);
4345 | break;
4346 | case FT_RELATIVE_TIME:
4347 | get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
4348 | *retval = rel_time_to_secs_str(scope, &time_stamp);
4349 | break;
4350 | default:
4351 | 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)
4352 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ABSOLUTE_TIME or FT_RELATIVE_TIME" , hfinfo->abbrev);
4353 | }
4354 |
4355 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4356 |
4357 | 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", 4357 , __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", 4357, "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", 4357, "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", 4357, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4358 |
4359 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4360 |
4361 | switch (hfinfo->type) {
4362 |
4363 | case FT_ABSOLUTE_TIME:
4364 | case FT_RELATIVE_TIME:
4365 | proto_tree_set_time(new_fi, &time_stamp);
4366 | break;
4367 | default:
4368 | ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4368 , __func__, "assertion \"not reached\" failed");
4369 | }
4370 |
4371 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4372 |
4373 | return proto_tree_add_node(tree, new_fi);
4374 | }
4375 |
4376 | /* Gets data from tvbuff, adds it to proto_tree, increments offset,
4377 | and returns proto_item* */
4378 | proto_item *
4379 | ptvcursor_add(ptvcursor_t *ptvc, int hfindex, int length,
4380 | const unsigned encoding)
4381 | {
4382 | field_info *new_fi;
4383 | header_field_info *hfinfo;
4384 | int item_length;
4385 | int offset;
4386 |
4387 | offset = ptvc->offset;
4388 | 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", 4388, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4388, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4388, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4389 | get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
4390 | test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
4391 |
4392 | ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
4393 |
4394 | CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
4395 |
4396 | /* Coast clear. Try and fake it */
4397 | 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", 4397 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4397, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4397, "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", 4397, __func__, "Adding %s would put more than %d 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); } } };
4398 |
4399 | new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
4400 |
4401 | return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
4402 | offset, length, encoding);
4403 | }
4404 |
4405 | /* Add an item to a proto_tree, using the text label registered to that item;
4406 | the item is extracted from the tvbuff handed to it. */
4407 | proto_item *
4408 | proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
4409 | const int start, int length, const unsigned encoding)
4410 | {
4411 | field_info *new_fi;
4412 | int item_length;
4413 |
4414 | 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", 4414, "hfinfo != ((void*)0)", "Not passed hfi!"))));
4415 |
4416 | get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4417 | test_length(hfinfo, tvb, start, item_length, encoding);
4418 |
4419 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4420 |
4421 | 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", 4421 , __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", 4421, "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", 4421, "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", 4421, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4422 |
4423 | new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4424 |
4425 | return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4426 | }
4427 |
4428 | proto_item *
4429 | proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4430 | const int start, int length, const unsigned encoding)
4431 | {
4432 | register header_field_info *hfinfo;
4433 |
4434 | 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", 4434, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4434, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4434, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4435 | return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
4436 | }
4437 |
4438 | /* Add an item to a proto_tree, using the text label registered to that item;
4439 | the item is extracted from the tvbuff handed to it.
4440 |
4441 | Return the length of the item through the pointer. */
4442 | proto_item *
4443 | proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
4444 | tvbuff_t *tvb, const int start,
4445 | int length, const unsigned encoding,
4446 | int *lenretval)
4447 | {
4448 | field_info *new_fi;
4449 | int item_length;
4450 | proto_item *item;
4451 |
4452 | 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", 4452, "hfinfo != ((void*)0)", "Not passed hfi!"))));
4453 |
4454 | get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4455 | test_length(hfinfo, tvb, start, item_length, encoding);
4456 |
4457 | if (!tree) {
4458 | /*
4459 | * We need to get the correct item length here.
4460 | * That's normally done by proto_tree_new_item(),
4461 | * but we won't be calling it.
4462 | */
4463 | *lenretval = get_full_length(hfinfo, tvb, start, length,
4464 | item_length, encoding);
4465 | return NULL((void*)0);
4466 | }
4467 |
4468 | 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", 4475 , __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", 4475, "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", 4475, "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", 4475 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4469 | /*((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", 4475 , __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", 4475, "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", 4475, "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", 4475 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4470 | * 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", 4475 , __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", 4475, "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", 4475, "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", 4475 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4471 | * 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", 4475 , __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", 4475, "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", 4475, "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", 4475 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4472 | */((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", 4475 , __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", 4475, "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", 4475, "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", 4475 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4473 | *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", 4475 , __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", 4475, "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", 4475, "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", 4475 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4474 | 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", 4475 , __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", 4475, "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", 4475, "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", 4475 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4475 | })((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", 4475 , __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", 4475, "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", 4475, "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", 4475 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } };
4476 |
4477 | new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4478 |
4479 | item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4480 | *lenretval = new_fi->length;
4481 | return item;
4482 | }
4483 |
4484 | proto_item *
4485 | proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4486 | const int start, int length,
4487 | const unsigned encoding, int *lenretval)
4488 | {
4489 | register header_field_info *hfinfo;
4490 |
4491 | 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", 4491, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4491, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4491, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4492 | return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, lenretval);
4493 | }
4494 |
4495 | /* which FT_ types can use proto_tree_add_bytes_item() */
4496 | static inline bool_Bool
4497 | validate_proto_tree_add_bytes_ftype(const enum ftenum type)
4498 | {
4499 | return (type == FT_BYTES ||
4500 | type == FT_UINT_BYTES ||
4501 | type == FT_OID ||
4502 | type == FT_REL_OID ||
4503 | type == FT_SYSTEM_ID );
4504 | }
4505 |
4506 | /* Note: this does no validation that the byte array of an FT_OID or
4507 | FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
4508 | so I think it's ok to continue not validating it?
4509 | */
4510 | proto_item *
4511 | proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4512 | const unsigned start, unsigned length,
4513 | const unsigned encoding,
4514 | GByteArray *retval, unsigned *endoff, int *err)
4515 | {
4516 | field_info *new_fi;
4517 | GByteArray *bytes = retval;
4518 | GByteArray *created_bytes = NULL((void*)0);
4519 | bool_Bool failed = false0;
4520 | uint32_t n = 0;
4521 | header_field_info *hfinfo;
4522 | bool_Bool generate = (bytes || tree) ? true1 : false0;
4523 |
4524 | 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", 4524, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4524, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4524, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4525 |
4526 | 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", 4526, "hfinfo != ((void*)0)", "Not passed hfi!"))));
4527 |
4528 | 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", 4529, "validate_proto_tree_add_bytes_ftype(hfinfo->type)" , "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type" ))))
4529 | "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", 4529, "validate_proto_tree_add_bytes_ftype(hfinfo->type)" , "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type" ))));
4530 |
4531 | if (length == 0) {
4532 | return NULL((void*)0);
4533 | }
4534 |
4535 | if (encoding & ENC_STR_NUM0x01000000) {
4536 | 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" );
4537 | }
4538 |
4539 | if (generate && (encoding & ENC_STR_HEX0x02000000)) {
4540 | if (hfinfo->type == FT_UINT_BYTES) {
4541 | /* can't decode FT_UINT_BYTES from strings */
4542 | 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")
4543 | "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");
4544 | }
4545 |
4546 | unsigned hex_encoding = encoding;
4547 | if (!(encoding & ENC_SEP_MASK0x001F0000)) {
4548 | /* If none of the separator values are used,
4549 | * assume no separator (the common case). */
4550 | hex_encoding |= ENC_SEP_NONE0x00010000;
4551 | #if 0
4552 | 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")
4553 | "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");
4554 | #endif
4555 | }
4556 |
4557 | if (!bytes) {
4558 | /* caller doesn't care about return value, but we need it to
4559 | call tvb_get_string_bytes() and set the tree later */
4560 | bytes = created_bytes = g_byte_array_new();
4561 | }
4562 |
4563 | /*
4564 | * bytes might be NULL after this, but can't add expert
4565 | * error until later; if it's NULL, just note that
4566 | * it failed.
4567 | */
4568 | bytes = tvb_get_string_bytes(tvb, start, length, hex_encoding, bytes, endoff);
4569 | if (bytes == NULL((void*)0))
4570 | failed = true1;
4571 | }
4572 | else if (generate) {
4573 | tvb_ensure_bytes_exist(tvb, start, length);
4574 |
4575 | if (hfinfo->type == FT_UINT_BYTES) {
4576 | n = length; /* n is now the "header" length */
4577 | length = get_uint_value(tree, tvb, start, n, encoding);
4578 | /* length is now the value's length; only store the value in the array */
4579 | tvb_ensure_bytes_exist(tvb, start + n, length);
4580 | if (!bytes) {
4581 | /* caller doesn't care about return value, but
4582 | * we may need it to set the tree later */
4583 | bytes = created_bytes = g_byte_array_new();
4584 | }
4585 | g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
4586 | }
4587 | else if (length > 0) {
4588 | if (!bytes) {
4589 | /* caller doesn't care about return value, but
4590 | * we may need it to set the tree later */
4591 | bytes = created_bytes = g_byte_array_new();
4592 | }
4593 | g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
4594 | }
4595 |
4596 | if (endoff)
4597 | *endoff = start + n + length;
4598 | }
4599 |
4600 | if (err)
4601 | *err = failed ? EINVAL22 : 0;
4602 |
4603 | 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); }
4604 | {if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes , 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return ((void*)0); }
4605 | 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); }
4606 | 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); }
4607 | 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); }
4608 | bytes = NULL;if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes , 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return ((void*)0); }
4609 | } )if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes , 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return ((void*)0); };
4610 |
4611 | 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", 4617 , __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", 4617, "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", 4617, "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", 4617 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4612 | {((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", 4617 , __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", 4617, "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", 4617, "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", 4617 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4613 | 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", 4617 , __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", 4617, "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", 4617, "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", 4617 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4614 | 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", 4617 , __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", 4617, "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", 4617, "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", 4617 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4615 | 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", 4617 , __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", 4617, "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", 4617, "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", 4617 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4616 | 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", 4617 , __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", 4617, "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", 4617, "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", 4617 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4617 | } )((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", 4617 , __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", 4617, "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", 4617, "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", 4617 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } };
4618 |
4619 | /* n will be zero except when it's a FT_UINT_BYTES */
4620 | new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
4621 |
4622 | if (encoding & ENC_STRING0x03000000) {
4623 | if (failed)
4624 | expert_add_info(NULL((void*)0), tree, &ei_byte_array_string_decoding_failed_error);
4625 |
4626 | if (bytes)
4627 | proto_tree_set_bytes_gbytearray(new_fi, bytes);
4628 | else
4629 | proto_tree_set_bytes(new_fi, NULL((void*)0), 0);
4630 |
4631 | if (created_bytes)
4632 | g_byte_array_free(created_bytes, true1);
4633 | }
4634 | else {
4635 | /* n will be zero except when it's a FT_UINT_BYTES */
4636 | proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
4637 |
4638 | /* XXX: If we have a non-NULL tree but NULL retval, we don't
4639 | * use the byte array created above in this case.
4640 | */
4641 | if (created_bytes)
4642 | g_byte_array_free(created_bytes, true1);
4643 |
4644 | FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | (( encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while (0)
4645 | (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);
4646 | }
4647 |
4648 | return proto_tree_add_node(tree, new_fi);
4649 | }
4650 |
4651 |
4652 | proto_item *
4653 | proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4654 | const unsigned start, const unsigned length,
4655 | const unsigned encoding,
4656 | nstime_t *retval, unsigned *endoff, int *err)
4657 | {
4658 | field_info *new_fi;
4659 | nstime_t time_stamp;
4660 | int saved_err = 0;
4661 | header_field_info *hfinfo;
4662 |
4663 | 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", 4663, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4663, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4663, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4664 |
4665 | 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", 4665, "hfinfo != ((void*)0)", "Not passed hfi!"))));
4666 |
4667 | if (length == 0) {
4668 | if(retval) {
4669 | nstime_set_zero(retval);
4670 | }
4671 | return NULL((void*)0);
4672 | }
4673 |
4674 | nstime_set_zero(&time_stamp);
4675 |
4676 | if (encoding & ENC_STR_TIME_MASK0x001F0000) {
4677 | 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", 4677, ((hfinfo))->abbrev))));
4678 | /* The only string format that could be a relative time is
4679 | * ENC_ISO_8601_TIME, and that is treated as an absolute time
4680 | * relative to "now" currently.
4681 | */
4682 | if (!tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff))
4683 | saved_err = EINVAL22;
4684 | }
4685 | else {
4686 | 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", 4686, ((hfinfo))->abbrev))));
4687 | const bool_Bool is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? true1 : false0;
4688 |
4689 | tvb_ensure_bytes_exist(tvb, start, length);
4690 | get_time_value(tree, tvb, start, length, encoding, &time_stamp, is_relative);
4691 | if (endoff) *endoff = start + length;
4692 | }
4693 |
4694 | if (err) *err = saved_err;
4695 |
4696 | if (retval) {
4697 | retval->secs = time_stamp.secs;
4698 | retval->nsecs = time_stamp.nsecs;
4699 | }
4700 |
4701 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4702 |
4703 | 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", 4703 , __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", 4703, "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", 4703, "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", 4703, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4704 |
4705 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4706 |
4707 | proto_tree_set_time(new_fi, &time_stamp);
4708 |
4709 | if (encoding & ENC_STRING0x03000000) {
4710 | if (saved_err)
4711 | expert_add_info(NULL((void*)0), tree, &ei_date_time_string_decoding_failed_error);
4712 | }
4713 | else {
4714 | FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | (( encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while (0)
4715 | (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);
4716 | }
4717 |
4718 | return proto_tree_add_node(tree, new_fi);
4719 | }
4720 |
4721 | /* Add a FT_NONE to a proto_tree */
4722 | proto_item *
4723 | proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
4724 | const int start, int length, const char *format,
4725 | ...)
4726 | {
4727 | proto_item *pi;
4728 | va_list ap;
4729 | header_field_info *hfinfo;
4730 |
4731 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4732 |
4733 | 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", 4733 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4733, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4733, "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", 4733, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4734 |
4735 | 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", 4735 , ((hfinfo))->abbrev))));
4736 |
4737 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4738 |
4739 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 4739, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
4740 |
4741 | va_start(ap, format)__builtin_va_start(ap, format);
4742 | proto_tree_set_representation(pi, format, ap);
4743 | va_end(ap)__builtin_va_end(ap);
4744 |
4745 | /* no value to set for FT_NONE */
4746 | return pi;
4747 | }
4748 |
4749 | /* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
4750 | * offset, and returns proto_item* */
4751 | proto_item *
4752 | ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, int length,
4753 | const unsigned encoding)
4754 | {
4755 | proto_item *item;
4756 |
4757 | item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
4758 | length, encoding);
4759 |
4760 | return item;
4761 | }
4762 |
4763 | /* Advance the ptvcursor's offset within its tvbuff without
4764 | * adding anything to the proto_tree. */
4765 | void
4766 | ptvcursor_advance(ptvcursor_t* ptvc, int length)
4767 | {
4768 | if (ckd_add(&ptvc->offset, ptvc->offset, length)__builtin_add_overflow((ptvc->offset), (length), (&ptvc ->offset))) {
4769 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
4770 | }
4771 | }
4772 |
4773 |
4774 | static void
4775 | proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length)
4776 | {
4777 | fvalue_set_protocol(fi->value, tvb, field_data, length);
4778 | }
4779 |
4780 | /* Add a FT_PROTOCOL to a proto_tree */
4781 | proto_item *
4782 | proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4783 | int start, int length, const char *format, ...)
4784 | {
4785 | proto_item *pi;
4786 | tvbuff_t *protocol_tvb;
4787 | va_list ap;
4788 | header_field_info *hfinfo;
4789 | char* protocol_rep;
4790 |
4791 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4792 |
4793 | 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", 4793 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4793, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4793, "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", 4793, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4794 |
4795 | 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" , 4795, ((hfinfo))->abbrev))));
4796 |
4797 | /*
4798 | * This can throw an exception, so do it before we allocate anything.
4799 | */
4800 | protocol_tvb = (start == 0 ? tvb : tvb_new_subset_length(tvb, start, length));
4801 |
4802 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4803 |
4804 | va_start(ap, format)__builtin_va_start(ap, format);
4805 | protocol_rep = ws_strdup_vprintf(format, ap)wmem_strdup_vprintf(((void*)0), format, ap);
4806 | proto_tree_set_protocol_tvb(PNODE_FINFO(pi)((pi)->finfo), protocol_tvb, protocol_rep, length);
4807 | g_free(protocol_rep);
4808 | va_end(ap)__builtin_va_end(ap);
4809 |
4810 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 4810, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
4811 |
4812 | va_start(ap, format)__builtin_va_start(ap, format);
4813 | proto_tree_set_representation(pi, format, ap);
4814 | va_end(ap)__builtin_va_end(ap);
4815 |
4816 | return pi;
4817 | }
4818 |
4819 | /* Add a FT_BYTES to a proto_tree */
4820 | proto_item *
4821 | proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4822 | int length, const uint8_t *start_ptr)
4823 | {
4824 | proto_item *pi;
4825 | header_field_info *hfinfo;
4826 | int item_length;
4827 |
4828 | 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", 4828, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4828, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4828, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4829 | get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
4830 | test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4831 |
4832 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4833 |
4834 | 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", 4834 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4834, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4834, "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", 4834, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4835 |
4836 | 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", 4836, ((hfinfo))->abbrev))));
4837 |
4838 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4839 | proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, length);
4840 |
4841 | return pi;
4842 | }
4843 |
4844 | /* Add a FT_BYTES to a proto_tree */
4845 | proto_item *
4846 | proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4847 | int tvbuff_length, const uint8_t *start_ptr, int ptr_length)
4848 | {
4849 | proto_item *pi;
4850 | header_field_info *hfinfo;
4851 | int item_length;
4852 |
4853 | 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", 4853, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4853, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4853, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4854 | get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length, ENC_NA0x00000000);
4855 | test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4856 |
4857 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4858 |
4859 | 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", 4859 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4859, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4859, "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", 4859, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4860 |
4861 | 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", 4861, ((hfinfo))->abbrev))));
4862 |
4863 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
4864 | proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, ptr_length);
4865 |
4866 | return pi;
4867 | }
4868 |
4869 | proto_item *
4870 | proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4871 | int start, int length,
4872 | const uint8_t *start_ptr,
4873 | const char *format, ...)
4874 | {
4875 | proto_item *pi;
4876 | va_list ap;
4877 |
4878 | if (start_ptr == NULL((void*)0))
4879 | start_ptr = tvb_get_ptr(tvb, start, length);
4880 |
4881 | pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4882 |
4883 | 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; };
4884 |
4885 | va_start(ap, format)__builtin_va_start(ap, format);
4886 | proto_tree_set_representation_value(pi, format, ap);
4887 | va_end(ap)__builtin_va_end(ap);
4888 |
4889 | return pi;
4890 | }
4891 |
4892 | proto_item *
4893 | proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4894 | int start, int length, const uint8_t *start_ptr,
4895 | const char *format, ...)
4896 | {
4897 | proto_item *pi;
4898 | va_list ap;
4899 |
4900 | if (start_ptr == NULL((void*)0))
4901 | start_ptr = tvb_get_ptr(tvb, start, length);
4902 |
4903 | pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4904 |
4905 | 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; };
4906 |
4907 | va_start(ap, format)__builtin_va_start(ap, format);
4908 | proto_tree_set_representation(pi, format, ap);
4909 | va_end(ap)__builtin_va_end(ap);
4910 |
4911 | return pi;
4912 | }
4913 |
4914 | static void
4915 | proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length)
4916 | {
4917 | DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4917, "length >= 0" ))));
4918 | 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", 4918, "start_ptr != ((void*)0) || length == 0" ))));
4919 |
4920 | fvalue_set_bytes_data(fi->value, start_ptr, length);
4921 | }
4922 |
4923 |
4924 | static void
4925 | proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, int offset, int length)
4926 | {
4927 | tvb_ensure_bytes_exist(tvb, offset, length);
4928 | proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
4929 | }
4930 |
4931 | static void
4932 | proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
4933 | {
4934 | GByteArray *bytes;
4935 |
4936 | DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4936, "value != ((void*)0)" ))));
4937 |
4938 | bytes = byte_array_dup(value);
4939 |
4940 | fvalue_set_byte_array(fi->value, bytes);
4941 | }
4942 |
4943 | /* Add a FT_*TIME to a proto_tree */
4944 | proto_item *
4945 | proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4946 | int length, const nstime_t *value_ptr)
4947 | {
4948 | proto_item *pi;
4949 | header_field_info *hfinfo;
4950 |
4951 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4952 |
4953 | 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", 4953 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4953, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4953, "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", 4953, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4954 |
4955 | 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", 4955, ((hfinfo))->abbrev))));
4956 |
4957 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4958 | proto_tree_set_time(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
4959 |
4960 | return pi;
4961 | }
4962 |
4963 | proto_item *
4964 | proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4965 | int start, int length, nstime_t *value_ptr,
4966 | const char *format, ...)
4967 | {
4968 | proto_item *pi;
4969 | va_list ap;
4970 |
4971 | pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
4972 | if (pi != tree) {
4973 | va_start(ap, format)__builtin_va_start(ap, format);
4974 | proto_tree_set_representation_value(pi, format, ap);
4975 | va_end(ap)__builtin_va_end(ap);
4976 | }
4977 |
4978 | return pi;
4979 | }
4980 |
4981 | proto_item *
4982 | proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4983 | int start, int length, nstime_t *value_ptr,
4984 | const char *format, ...)
4985 | {
4986 | proto_item *pi;
4987 | va_list ap;
4988 |
4989 | pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
4990 | if (pi != tree) {
4991 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 4991, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
4992 |
4993 | va_start(ap, format)__builtin_va_start(ap, format);
4994 | proto_tree_set_representation(pi, format, ap);
4995 | va_end(ap)__builtin_va_end(ap);
4996 | }
4997 |
4998 | return pi;
4999 | }
5000 |
5001 | /* Set the FT_*TIME value */
5002 | static void
5003 | proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
5004 | {
5005 | DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5005, "value_ptr != ((void*)0)" ))));
5006 |
5007 | fvalue_set_time(fi->value, value_ptr);
5008 | }
5009 |
5010 | /* Add a FT_IPXNET to a proto_tree */
5011 | proto_item *
5012 | proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5013 | int length, uint32_t value)
5014 | {
5015 | proto_item *pi;
5016 | header_field_info *hfinfo;
5017 |
5018 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5019 |
5020 | 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", 5020 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5020, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5020, "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", 5020, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5021 |
5022 | 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" , 5022, ((hfinfo))->abbrev))));
5023 |
5024 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5025 | proto_tree_set_ipxnet(PNODE_FINFO(pi)((pi)->finfo), value);
5026 |
5027 | return pi;
5028 | }
5029 |
5030 | proto_item *
5031 | proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5032 | int start, int length, uint32_t value,
5033 | const char *format, ...)
5034 | {
5035 | proto_item *pi;
5036 | va_list ap;
5037 |
5038 | pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5039 | if (pi != tree) {
5040 | va_start(ap, format)__builtin_va_start(ap, format);
5041 | proto_tree_set_representation_value(pi, format, ap);
5042 | va_end(ap)__builtin_va_end(ap);
5043 | }
5044 |
5045 | return pi;
5046 | }
5047 |
5048 | proto_item *
5049 | proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5050 | int start, int length, uint32_t value,
5051 | const char *format, ...)
5052 | {
5053 | proto_item *pi;
5054 | va_list ap;
5055 |
5056 | pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5057 | if (pi != tree) {
5058 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5058, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5059 |
5060 | va_start(ap, format)__builtin_va_start(ap, format);
5061 | proto_tree_set_representation(pi, format, ap);
5062 | va_end(ap)__builtin_va_end(ap);
5063 | }
5064 |
5065 | return pi;
5066 | }
5067 |
5068 | /* Set the FT_IPXNET value */
5069 | static void
5070 | proto_tree_set_ipxnet(field_info *fi, uint32_t value)
5071 | {
5072 | fvalue_set_uinteger(fi->value, value);
5073 | }
5074 |
5075 | /* Add a FT_IPv4 to a proto_tree */
5076 | proto_item *
5077 | proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5078 | int length, ws_in4_addr value)
5079 | {
5080 | proto_item *pi;
5081 | header_field_info *hfinfo;
5082 |
5083 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5084 |
5085 | 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", 5085 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5085, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5085, "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", 5085, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5086 |
5087 | 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", 5087 , ((hfinfo))->abbrev))));
5088 |
5089 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5090 | proto_tree_set_ipv4(PNODE_FINFO(pi)((pi)->finfo), value);
5091 |
5092 | return pi;
5093 | }
5094 |
5095 | proto_item *
5096 | proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5097 | int start, int length, ws_in4_addr value,
5098 | const char *format, ...)
5099 | {
5100 | proto_item *pi;
5101 | va_list ap;
5102 |
5103 | pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5104 | if (pi != tree) {
5105 | va_start(ap, format)__builtin_va_start(ap, format);
5106 | proto_tree_set_representation_value(pi, format, ap);
5107 | va_end(ap)__builtin_va_end(ap);
5108 | }
5109 |
5110 | return pi;
5111 | }
5112 |
5113 | proto_item *
5114 | proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5115 | int start, int length, ws_in4_addr value,
5116 | const char *format, ...)
5117 | {
5118 | proto_item *pi;
5119 | va_list ap;
5120 |
5121 | pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5122 | if (pi != tree) {
5123 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5123, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5124 |
5125 | va_start(ap, format)__builtin_va_start(ap, format);
5126 | proto_tree_set_representation(pi, format, ap);
5127 | va_end(ap)__builtin_va_end(ap);
5128 | }
5129 |
5130 | return pi;
5131 | }
5132 |
5133 | /* Set the FT_IPv4 value */
5134 | static void
5135 | proto_tree_set_ipv4(field_info *fi, ws_in4_addr value)
5136 | {
5137 | ipv4_addr_and_mask ipv4;
5138 | ws_ipv4_addr_and_mask_init(&ipv4, value, 32);
5139 | fvalue_set_ipv4(fi->value, &ipv4);
5140 | }
5141 |
5142 | /* Add a FT_IPv6 to a proto_tree */
5143 | proto_item *
5144 | proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5145 | int length, const ws_in6_addr *value)
5146 | {
5147 | proto_item *pi;
5148 | header_field_info *hfinfo;
5149 |
5150 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5151 |
5152 | 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", 5152 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5152, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5152, "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", 5152, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5153 |
5154 | 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", 5154 , ((hfinfo))->abbrev))));
5155 |
5156 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5157 | proto_tree_set_ipv6(PNODE_FINFO(pi)((pi)->finfo), value);
5158 |
5159 | return pi;
5160 | }
5161 |
5162 | proto_item *
5163 | proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5164 | int start, int length,
5165 | const ws_in6_addr *value_ptr,
5166 | const char *format, ...)
5167 | {
5168 | proto_item *pi;
5169 | va_list ap;
5170 |
5171 | pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5172 | if (pi != tree) {
5173 | va_start(ap, format)__builtin_va_start(ap, format);
5174 | proto_tree_set_representation_value(pi, format, ap);
5175 | va_end(ap)__builtin_va_end(ap);
5176 | }
5177 |
5178 | return pi;
5179 | }
5180 |
5181 | proto_item *
5182 | proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5183 | int start, int length,
5184 | const ws_in6_addr *value_ptr,
5185 | const char *format, ...)
5186 | {
5187 | proto_item *pi;
5188 | va_list ap;
5189 |
5190 | pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5191 | if (pi != tree) {
5192 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5192, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5193 |
5194 | va_start(ap, format)__builtin_va_start(ap, format);
5195 | proto_tree_set_representation(pi, format, ap);
5196 | va_end(ap)__builtin_va_end(ap);
5197 | }
5198 |
5199 | return pi;
5200 | }
5201 |
5202 | /* Set the FT_IPv6 value */
5203 | static void
5204 | proto_tree_set_ipv6(field_info *fi, const ws_in6_addr *value)
5205 | {
5206 | DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5206, "value != ((void*)0)" ))));
5207 | ipv6_addr_and_prefix ipv6;
5208 | ipv6.addr = *value;
5209 | ipv6.prefix = 128;
5210 | fvalue_set_ipv6(fi->value, &ipv6);
5211 | }
5212 |
5213 | static void
5214 | proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5215 | {
5216 | proto_tree_set_ipv6(fi, (const ws_in6_addr *)tvb_get_ptr(tvb, start, length));
5217 | }
5218 |
5219 | /* Set the FT_FCWWN value */
5220 | static void
5221 | proto_tree_set_fcwwn(field_info *fi, const uint8_t* value_ptr)
5222 | {
5223 | DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5223, "value_ptr != ((void*)0)" ))));
5224 | fvalue_set_fcwwn(fi->value, value_ptr);
5225 | }
5226 |
5227 | static void
5228 | proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5229 | {
5230 | proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
5231 | }
5232 |
5233 | /* Add a FT_GUID to a proto_tree */
5234 | proto_item *
5235 | proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5236 | int length, const e_guid_t *value_ptr)
5237 | {
5238 | proto_item *pi;
5239 | header_field_info *hfinfo;
5240 |
5241 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5242 |
5243 | 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", 5243 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5243, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5243, "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", 5243, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5244 |
5245 | 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", 5245 , ((hfinfo))->abbrev))));
5246 |
5247 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5248 | proto_tree_set_guid(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5249 |
5250 | return pi;
5251 | }
5252 |
5253 | proto_item *
5254 | proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5255 | int start, int length,
5256 | const e_guid_t *value_ptr,
5257 | const char *format, ...)
5258 | {
5259 | proto_item *pi;
5260 | va_list ap;
5261 |
5262 | pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5263 | if (pi != tree) {
5264 | va_start(ap, format)__builtin_va_start(ap, format);
5265 | proto_tree_set_representation_value(pi, format, ap);
5266 | va_end(ap)__builtin_va_end(ap);
5267 | }
5268 |
5269 | return pi;
5270 | }
5271 |
5272 | proto_item *
5273 | proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5274 | int start, int length, const e_guid_t *value_ptr,
5275 | const char *format, ...)
5276 | {
5277 | proto_item *pi;
5278 | va_list ap;
5279 |
5280 | pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5281 | if (pi != tree) {
5282 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5282, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5283 |
5284 | va_start(ap, format)__builtin_va_start(ap, format);
5285 | proto_tree_set_representation(pi, format, ap);
5286 | va_end(ap)__builtin_va_end(ap);
5287 | }
5288 |
5289 | return pi;
5290 | }
5291 |
5292 | /* Set the FT_GUID value */
5293 | static void
5294 | proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
5295 | {
5296 | DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5296, "value_ptr != ((void*)0)" ))));
5297 | fvalue_set_guid(fi->value, value_ptr);
5298 | }
5299 |
5300 | static void
5301 | proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, int start,
5302 | const unsigned encoding)
5303 | {
5304 | e_guid_t guid;
5305 |
5306 | tvb_get_guid(tvb, start, &guid, encoding);
5307 | proto_tree_set_guid(fi, &guid);
5308 | }
5309 |
5310 | /* Add a FT_OID to a proto_tree */
5311 | proto_item *
5312 | proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5313 | int length, const uint8_t* value_ptr)
5314 | {
5315 | proto_item *pi;
5316 | header_field_info *hfinfo;
5317 |
5318 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5319 |
5320 | 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", 5320 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5320, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5320, "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", 5320, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5321 |
5322 | 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", 5322 , ((hfinfo))->abbrev))));
5323 |
5324 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5325 | proto_tree_set_oid(PNODE_FINFO(pi)((pi)->finfo), value_ptr, length);
5326 |
5327 | return pi;
5328 | }
5329 |
5330 | proto_item *
5331 | proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5332 | int start, int length,
5333 | const uint8_t* value_ptr,
5334 | const char *format, ...)
5335 | {
5336 | proto_item *pi;
5337 | va_list ap;
5338 |
5339 | pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5340 | if (pi != tree) {
5341 | va_start(ap, format)__builtin_va_start(ap, format);
5342 | proto_tree_set_representation_value(pi, format, ap);
5343 | va_end(ap)__builtin_va_end(ap);
5344 | }
5345 |
5346 | return pi;
5347 | }
5348 |
5349 | proto_item *
5350 | proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5351 | int start, int length, const uint8_t* value_ptr,
5352 | const char *format, ...)
5353 | {
5354 | proto_item *pi;
5355 | va_list ap;
5356 |
5357 | pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5358 | if (pi != tree) {
5359 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5359, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5360 |
5361 | va_start(ap, format)__builtin_va_start(ap, format);
5362 | proto_tree_set_representation(pi, format, ap);
5363 | va_end(ap)__builtin_va_end(ap);
5364 | }
5365 |
5366 | return pi;
5367 | }
5368 |
5369 | /* Set the FT_OID value */
5370 | static void
5371 | proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, int length)
5372 | {
5373 | GByteArray *bytes;
5374 |
5375 | 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", 5375, "value_ptr != ((void*)0) || length == 0" ))));
5376 |
5377 | bytes = g_byte_array_new();
5378 | if (length > 0) {
5379 | g_byte_array_append(bytes, value_ptr, length);
5380 | }
5381 | fvalue_set_byte_array(fi->value, bytes);
5382 | }
5383 |
5384 | static void
5385 | proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5386 | {
5387 | proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
5388 | }
5389 |
5390 | /* Set the FT_SYSTEM_ID value */
5391 | static void
5392 | proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, int length)
5393 | {
5394 | GByteArray *bytes;
5395 |
5396 | 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", 5396, "value_ptr != ((void*)0) || length == 0" ))));
5397 |
5398 | bytes = g_byte_array_new();
5399 | if (length > 0) {
5400 | g_byte_array_append(bytes, value_ptr, length);
5401 | }
5402 | fvalue_set_byte_array(fi->value, bytes);
5403 | }
5404 |
5405 | static void
5406 | proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5407 | {
5408 | proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
5409 | }
5410 |
5411 | /* Add a FT_STRING, FT_STRINGZ, FT_STRINGZPAD, or FT_STRINGZTRUNC to a
5412 | * proto_tree. Creates own copy of string, and frees it when the proto_tree
5413 | * is destroyed. */
5414 | proto_item *
5415 | proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5416 | int length, const char* value)
5417 | {
5418 | proto_item *pi;
5419 | header_field_info *hfinfo;
5420 | int item_length;
5421 |
5422 | 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", 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];;
5423 | get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
5424 | /*
5425 | * Special case - if the length is 0, skip the test, so that
5426 | * we can have an empty string right after the end of the
5427 | * packet. (This handles URL-encoded forms where the last field
5428 | * has no value so the form ends right after the =.)
5429 | *
5430 | * XXX - length zero makes sense for FT_STRING, and more or less
5431 | * for FT_STRINGZTRUNC, and FT_STRINGZPAD, but doesn't make sense
5432 | * for FT_STRINGZ (except that a number of fields that should be
5433 | * one of the others are actually registered as FT_STRINGZ.)
5434 | */
5435 | if (item_length != 0)
5436 | test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
5437 |
5438 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5439 |
5440 | 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", 5440 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5440, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5440, "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", 5440, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5441 |
5442 | 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", 5442, ((hfinfo))->abbrev))));
5443 |
5444 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5445 | DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5445, "length >= 0" ))));
5446 |
5447 | 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", 5447, __func__, value, -1, __uni_endptr); } } while (0); } } while (0);
5448 | proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), value);
5449 |
5450 | return pi;
5451 | }
5452 |
5453 | proto_item *
5454 | proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5455 | int start, int length, const char* value,
5456 | const char *format,
5457 | ...)
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 | va_start(ap, format)__builtin_va_start(ap, format);
5465 | proto_tree_set_representation_value(pi, format, ap);
5466 | va_end(ap)__builtin_va_end(ap);
5467 | }
5468 |
5469 | return pi;
5470 | }
5471 |
5472 | proto_item *
5473 | proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5474 | int start, int length, const char* value,
5475 | const char *format, ...)
5476 | {
5477 | proto_item *pi;
5478 | va_list ap;
5479 |
5480 | pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5481 | if (pi != tree) {
5482 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5482, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5483 |
5484 | va_start(ap, format)__builtin_va_start(ap, format);
5485 | proto_tree_set_representation(pi, format, ap);
5486 | va_end(ap)__builtin_va_end(ap);
5487 | }
5488 |
5489 | return pi;
5490 | }
5491 |
5492 | /* Set the FT_STRING value */
5493 | static void
5494 | proto_tree_set_string(field_info *fi, const char* value)
5495 | {
5496 | if (value) {
5497 | fvalue_set_string(fi->value, value);
5498 | } else {
5499 | /*
5500 | * XXX - why is a null value for a string field
5501 | * considered valid?
5502 | */
5503 | fvalue_set_string(fi->value, "[ Null ]");
5504 | }
5505 | }
5506 |
5507 | /* Set the FT_AX25 value */
5508 | static void
5509 | proto_tree_set_ax25(field_info *fi, const uint8_t* value)
5510 | {
5511 | fvalue_set_ax25(fi->value, value);
5512 | }
5513 |
5514 | static void
5515 | proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, int start)
5516 | {
5517 | proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
5518 | }
5519 |
5520 | /* Set the FT_VINES value */
5521 | static void
5522 | proto_tree_set_vines(field_info *fi, const uint8_t* value)
5523 | {
5524 | fvalue_set_vines(fi->value, value);
5525 | }
5526 |
5527 | static void
5528 | proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, int start)
5529 | {
5530 | proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN6));
5531 | }
5532 |
5533 | /* Add a FT_ETHER to a proto_tree */
5534 | proto_item *
5535 | proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5536 | int length, const uint8_t* value)
5537 | {
5538 | proto_item *pi;
5539 | header_field_info *hfinfo;
5540 |
5541 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5542 |
5543 | 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", 5543 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5543, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5543, "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", 5543, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5544 |
5545 | 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", 5545, ((hfinfo))->abbrev))));
5546 |
5547 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5548 | proto_tree_set_ether(PNODE_FINFO(pi)((pi)->finfo), value);
5549 |
5550 | return pi;
5551 | }
5552 |
5553 | proto_item *
5554 | proto_tree_add_ether_format_value(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 | va_start(ap, format)__builtin_va_start(ap, format);
5564 | proto_tree_set_representation_value(pi, format, ap);
5565 | va_end(ap)__builtin_va_end(ap);
5566 | }
5567 |
5568 | return pi;
5569 | }
5570 |
5571 | proto_item *
5572 | proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5573 | int start, int length, const uint8_t* value,
5574 | const char *format, ...)
5575 | {
5576 | proto_item *pi;
5577 | va_list ap;
5578 |
5579 | pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5580 | if (pi != tree) {
5581 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5581, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5582 |
5583 | va_start(ap, format)__builtin_va_start(ap, format);
5584 | proto_tree_set_representation(pi, format, ap);
5585 | va_end(ap)__builtin_va_end(ap);
5586 | }
5587 |
5588 | return pi;
5589 | }
5590 |
5591 | /* Set the FT_ETHER value */
5592 | static void
5593 | proto_tree_set_ether(field_info *fi, const uint8_t* value)
5594 | {
5595 | fvalue_set_ether(fi->value, value);
5596 | }
5597 |
5598 | static void
5599 | proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, int start)
5600 | {
5601 | proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN6));
5602 | }
5603 |
5604 | /* Add a FT_BOOLEAN to a proto_tree */
5605 | proto_item *
5606 | proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5607 | int length, uint64_t value)
5608 | {
5609 | proto_item *pi;
5610 | header_field_info *hfinfo;
5611 |
5612 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5613 |
5614 | 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", 5614 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5614, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5614, "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", 5614, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5615 |
5616 | 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" , 5616, ((hfinfo))->abbrev))));
5617 |
5618 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5619 | proto_tree_set_boolean(PNODE_FINFO(pi)((pi)->finfo), value);
5620 |
5621 | return pi;
5622 | }
5623 |
5624 | proto_item *
5625 | proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
5626 | tvbuff_t *tvb, int start, int length,
5627 | uint64_t value, 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 | va_start(ap, format)__builtin_va_start(ap, format);
5635 | proto_tree_set_representation_value(pi, format, ap);
5636 | va_end(ap)__builtin_va_end(ap);
5637 | }
5638 |
5639 | return pi;
5640 | }
5641 |
5642 | proto_item *
5643 | proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5644 | int start, int length, uint64_t value,
5645 | const char *format, ...)
5646 | {
5647 | proto_item *pi;
5648 | va_list ap;
5649 |
5650 | pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5651 | if (pi != tree) {
5652 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5652, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5653 |
5654 | va_start(ap, format)__builtin_va_start(ap, format);
5655 | proto_tree_set_representation(pi, format, ap);
5656 | va_end(ap)__builtin_va_end(ap);
5657 | }
5658 |
5659 | return pi;
5660 | }
5661 |
5662 | /* Set the FT_BOOLEAN value */
5663 | static void
5664 | proto_tree_set_boolean(field_info *fi, uint64_t value)
5665 | {
5666 | proto_tree_set_uint64(fi, value);
5667 | }
5668 |
5669 | /* Generate, into "buf", a string showing the bits of a bitfield.
5670 | Return a pointer to the character after that string. */
5671 | static char *
5672 | other_decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5673 | {
5674 | int i = 0;
5675 | uint64_t bit;
5676 | char *p;
5677 |
5678 | p = buf;
5679 |
5680 | /* This is a devel error. It is safer to stop here. */
5681 | DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5681, "width >= 1" ))));
5682 |
5683 | bit = UINT64_C(1)1UL << (width - 1);
5684 | for (;;) {
5685 | if (mask & bit) {
5686 | /* This bit is part of the field. Show its value. */
5687 | if (val & bit)
5688 | *p++ = '1';
5689 | else
5690 | *p++ = '0';
5691 | } else {
5692 | /* This bit is not part of the field. */
5693 | *p++ = '.';
5694 | }
5695 | bit >>= 1;
5696 | i++;
5697 | if (i >= width)
5698 | break;
5699 | if (i % 4 == 0)
5700 | *p++ = ' ';
5701 | }
5702 | *p = '\0';
5703 | return p;
5704 | }
5705 |
5706 | static char *
5707 | decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5708 | {
5709 | char *p;
5710 |
5711 | p = other_decode_bitfield_value(buf, val, mask, width);
5712 | p = g_stpcpy(p, " = ");
5713 |
5714 | return p;
5715 | }
5716 |
5717 | static char *
5718 | other_decode_bitfield_varint_value(char *buf, uint64_t val, uint64_t mask, const int width)
5719 | {
5720 | int i = 0;
5721 | uint64_t bit;
5722 | char *p;
5723 |
5724 | p = buf;
5725 |
5726 | /* This is a devel error. It is safer to stop here. */
5727 | DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5727, "width >= 1" ))));
5728 |
5729 | bit = UINT64_C(1)1UL << (width - 1);
5730 | for (;;) {
5731 | if (((8-(i % 8)) != 8) && /* MSB is never used for value. */
5732 | (mask & bit)) {
5733 | /* This bit is part of the field. Show its value. */
5734 | if (val & bit)
5735 | *p++ = '1';
5736 | else
5737 | *p++ = '0';
5738 | } else {
5739 | /* This bit is not part of the field. */
5740 | *p++ = '.';
5741 | }
5742 | bit >>= 1;
5743 | i++;
5744 | if (i >= width)
5745 | break;
5746 | if (i % 4 == 0)
5747 | *p++ = ' ';
5748 | }
5749 |
5750 | *p = '\0';
5751 | return p;
5752 | }
5753 |
5754 | static char *
5755 | decode_bitfield_varint_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5756 | {
5757 | char *p;
5758 |
5759 | p = other_decode_bitfield_varint_value(buf, val, mask, width);
5760 | p = g_stpcpy(p, " = ");
5761 |
5762 | return p;
5763 | }
5764 |
5765 | /* Add a FT_FLOAT to a proto_tree */
5766 | proto_item *
5767 | proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5768 | int length, float value)
5769 | {
5770 | proto_item *pi;
5771 | header_field_info *hfinfo;
5772 |
5773 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5774 |
5775 | 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", 5775 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5775, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5775, "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", 5775, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5776 |
5777 | 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", 5777, ((hfinfo))->abbrev))));
5778 |
5779 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5780 | proto_tree_set_float(PNODE_FINFO(pi)((pi)->finfo), value);
5781 |
5782 | return pi;
5783 | }
5784 |
5785 | proto_item *
5786 | proto_tree_add_float_format_value(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 | va_start(ap, format)__builtin_va_start(ap, format);
5796 | proto_tree_set_representation_value(pi, format, ap);
5797 | va_end(ap)__builtin_va_end(ap);
5798 | }
5799 |
5800 | return pi;
5801 | }
5802 |
5803 | proto_item *
5804 | proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5805 | int start, int length, float value,
5806 | const char *format, ...)
5807 | {
5808 | proto_item *pi;
5809 | va_list ap;
5810 |
5811 | pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5812 | if (pi != tree) {
5813 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5813, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5814 |
5815 | va_start(ap, format)__builtin_va_start(ap, format);
5816 | proto_tree_set_representation(pi, format, ap);
5817 | va_end(ap)__builtin_va_end(ap);
5818 | }
5819 |
5820 | return pi;
5821 | }
5822 |
5823 | /* Set the FT_FLOAT value */
5824 | static void
5825 | proto_tree_set_float(field_info *fi, float value)
5826 | {
5827 | fvalue_set_floating(fi->value, value);
5828 | }
5829 |
5830 | /* Add a FT_DOUBLE to a proto_tree */
5831 | proto_item *
5832 | proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5833 | int length, double value)
5834 | {
5835 | proto_item *pi;
5836 | header_field_info *hfinfo;
5837 |
5838 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5839 |
5840 | 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", 5840 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5840, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5840, "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", 5840, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5841 |
5842 | 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" , 5842, ((hfinfo))->abbrev))));
5843 |
5844 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5845 | proto_tree_set_double(PNODE_FINFO(pi)((pi)->finfo), value);
5846 |
5847 | return pi;
5848 | }
5849 |
5850 | proto_item *
5851 | proto_tree_add_double_format_value(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 | va_start(ap, format)__builtin_va_start(ap, format);
5861 | proto_tree_set_representation_value(pi, format, ap);
5862 | va_end(ap)__builtin_va_end(ap);
5863 | }
5864 |
5865 | return pi;
5866 | }
5867 |
5868 | proto_item *
5869 | proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5870 | int start, int length, double value,
5871 | const char *format, ...)
5872 | {
5873 | proto_item *pi;
5874 | va_list ap;
5875 |
5876 | pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5877 | if (pi != tree) {
5878 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5878, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5879 |
5880 | va_start(ap, format)__builtin_va_start(ap, format);
5881 | proto_tree_set_representation(pi, format, ap);
5882 | va_end(ap)__builtin_va_end(ap);
5883 | }
5884 |
5885 | return pi;
5886 | }
5887 |
5888 | /* Set the FT_DOUBLE value */
5889 | static void
5890 | proto_tree_set_double(field_info *fi, double value)
5891 | {
5892 | fvalue_set_floating(fi->value, value);
5893 | }
5894 |
5895 | /* Add FT_CHAR or FT_UINT{8,16,24,32} to a proto_tree */
5896 | proto_item *
5897 | proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5898 | int length, uint32_t value)
5899 | {
5900 | proto_item *pi = NULL((void*)0);
5901 | header_field_info *hfinfo;
5902 |
5903 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5904 |
5905 | 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", 5905 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5905, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5905, "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", 5905, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5906 |
5907 | switch (hfinfo->type) {
5908 | case FT_CHAR:
5909 | case FT_UINT8:
5910 | case FT_UINT16:
5911 | case FT_UINT24:
5912 | case FT_UINT32:
5913 | case FT_FRAMENUM:
5914 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5915 | proto_tree_set_uint(PNODE_FINFO(pi)((pi)->finfo), value);
5916 | break;
5917 |
5918 | default:
5919 | 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)
5920 | 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);
5921 | }
5922 |
5923 | return pi;
5924 | }
5925 |
5926 | proto_item *
5927 | proto_tree_add_uint_format_value(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 | va_start(ap, format)__builtin_va_start(ap, format);
5937 | proto_tree_set_representation_value(pi, format, ap);
5938 | va_end(ap)__builtin_va_end(ap);
5939 | }
5940 |
5941 | return pi;
5942 | }
5943 |
5944 | proto_item *
5945 | proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5946 | int start, int length, uint32_t value,
5947 | const char *format, ...)
5948 | {
5949 | proto_item *pi;
5950 | va_list ap;
5951 |
5952 | pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5953 | if (pi != tree) {
5954 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5954, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5955 |
5956 | va_start(ap, format)__builtin_va_start(ap, format);
5957 | proto_tree_set_representation(pi, format, ap);
5958 | va_end(ap)__builtin_va_end(ap);
5959 | }
5960 |
5961 | return pi;
5962 | }
5963 |
5964 | /* Set the FT_UINT{8,16,24,32} value */
5965 | static void
5966 | proto_tree_set_uint(field_info *fi, uint32_t value)
5967 | {
5968 | const header_field_info *hfinfo;
5969 | uint32_t integer;
5970 |
5971 | hfinfo = fi->hfinfo;
5972 | integer = value;
5973 |
5974 | if (hfinfo->bitmask) {
5975 | /* Mask out irrelevant portions */
5976 | integer &= (uint32_t)(hfinfo->bitmask);
5977 |
5978 | /* Shift bits */
5979 | integer >>= hfinfo_bitshift(hfinfo);
5980 |
5981 | FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset (hfinfo)) & 63) << 5)); } while(0);
5982 | 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);
5983 | }
5984 |
5985 | fvalue_set_uinteger(fi->value, integer);
5986 | }
5987 |
5988 | /* Add FT_UINT{40,48,56,64} to a proto_tree */
5989 | proto_item *
5990 | proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5991 | int length, uint64_t value)
5992 | {
5993 | proto_item *pi = NULL((void*)0);
5994 | header_field_info *hfinfo;
5995 |
5996 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5997 |
5998 | 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", 5998 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5998, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5998, "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", 5998, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5999 |
6000 | switch (hfinfo->type) {
6001 | case FT_UINT40:
6002 | case FT_UINT48:
6003 | case FT_UINT56:
6004 | case FT_UINT64:
6005 | case FT_FRAMENUM:
6006 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6007 | proto_tree_set_uint64(PNODE_FINFO(pi)((pi)->finfo), value);
6008 | break;
6009 |
6010 | default:
6011 | 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)
6012 | 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);
6013 | }
6014 |
6015 | return pi;
6016 | }
6017 |
6018 | proto_item *
6019 | proto_tree_add_uint64_format_value(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 | va_start(ap, format)__builtin_va_start(ap, format);
6029 | proto_tree_set_representation_value(pi, format, ap);
6030 | va_end(ap)__builtin_va_end(ap);
6031 | }
6032 |
6033 | return pi;
6034 | }
6035 |
6036 | proto_item *
6037 | proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6038 | int start, int length, uint64_t value,
6039 | const char *format, ...)
6040 | {
6041 | proto_item *pi;
6042 | va_list ap;
6043 |
6044 | pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6045 | if (pi != tree) {
6046 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6046, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
6047 |
6048 | va_start(ap, format)__builtin_va_start(ap, format);
6049 | proto_tree_set_representation(pi, format, ap);
6050 | va_end(ap)__builtin_va_end(ap);
6051 | }
6052 |
6053 | return pi;
6054 | }
6055 |
6056 | /* Set the FT_UINT{40,48,56,64} value */
6057 | static void
6058 | proto_tree_set_uint64(field_info *fi, uint64_t value)
6059 | {
6060 | const header_field_info *hfinfo;
6061 | uint64_t integer;
6062 |
6063 | hfinfo = fi->hfinfo;
6064 | integer = value;
6065 |
6066 | if (hfinfo->bitmask) {
6067 | /* Mask out irrelevant portions */
6068 | integer &= hfinfo->bitmask;
6069 |
6070 | /* Shift bits */
6071 | integer >>= hfinfo_bitshift(hfinfo);
6072 |
6073 | FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset (hfinfo)) & 63) << 5)); } while(0);
6074 | 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);
6075 | }
6076 |
6077 | fvalue_set_uinteger64(fi->value, integer);
6078 | }
6079 |
6080 | /* Add FT_INT{8,16,24,32} to a proto_tree */
6081 | proto_item *
6082 | proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6083 | int length, int32_t value)
6084 | {
6085 | proto_item *pi = NULL((void*)0);
6086 | header_field_info *hfinfo;
6087 |
6088 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6089 |
6090 | 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", 6090 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6090, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6090, "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", 6090, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
6091 |
6092 | switch (hfinfo->type) {
6093 | case FT_INT8:
6094 | case FT_INT16:
6095 | case FT_INT24:
6096 | case FT_INT32:
6097 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6098 | proto_tree_set_int(PNODE_FINFO(pi)((pi)->finfo), value);
6099 | break;
6100 |
6101 | default:
6102 | 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)
6103 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32" , hfinfo->abbrev);
6104 | }
6105 |
6106 | return pi;
6107 | }
6108 |
6109 | proto_item *
6110 | proto_tree_add_int_format_value(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 | va_start(ap, format)__builtin_va_start(ap, format);
6120 | proto_tree_set_representation_value(pi, format, ap);
6121 | va_end(ap)__builtin_va_end(ap);
6122 | }
6123 |
6124 | return pi;
6125 | }
6126 |
6127 | proto_item *
6128 | proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6129 | int start, int length, int32_t value,
6130 | const char *format, ...)
6131 | {
6132 | proto_item *pi;
6133 | va_list ap;
6134 |
6135 | pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6136 | if (pi != tree) {
6137 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6137, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
6138 |
6139 | va_start(ap, format)__builtin_va_start(ap, format);
6140 | proto_tree_set_representation(pi, format, ap);
6141 | va_end(ap)__builtin_va_end(ap);
6142 | }
6143 |
6144 | return pi;
6145 | }
6146 |
6147 | /* Set the FT_INT{8,16,24,32} value */
6148 | static void
6149 | proto_tree_set_int(field_info *fi, int32_t value)
6150 | {
6151 | const header_field_info *hfinfo;
6152 | uint32_t integer;
6153 | int no_of_bits;
6154 |
6155 | hfinfo = fi->hfinfo;
6156 | integer = (uint32_t) value;
6157 |
6158 | if (hfinfo->bitmask) {
6159 | /* Mask out irrelevant portions */
6160 | integer &= (uint32_t)(hfinfo->bitmask);
6161 |
6162 | /* Shift bits */
6163 | integer >>= hfinfo_bitshift(hfinfo);
6164 |
6165 | no_of_bits = ws_count_ones(hfinfo->bitmask);
6166 | integer = ws_sign_ext32(integer, no_of_bits);
6167 |
6168 | FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset (hfinfo)) & 63) << 5)); } while(0);
6169 | 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);
6170 | }
6171 |
6172 | fvalue_set_sinteger(fi->value, integer);
6173 | }
6174 |
6175 | /* Add FT_INT{40,48,56,64} to a proto_tree */
6176 | proto_item *
6177 | proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6178 | int length, int64_t value)
6179 | {
6180 | proto_item *pi = NULL((void*)0);
6181 | header_field_info *hfinfo;
6182 |
6183 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6184 |
6185 | 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", 6185 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6185, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6185, "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", 6185, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
6186 |
6187 | switch (hfinfo->type) {
6188 | case FT_INT40:
6189 | case FT_INT48:
6190 | case FT_INT56:
6191 | case FT_INT64:
6192 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6193 | proto_tree_set_int64(PNODE_FINFO(pi)((pi)->finfo), value);
6194 | break;
6195 |
6196 | default:
6197 | 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)
6198 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64" , hfinfo->abbrev);
6199 | }
6200 |
6201 | return pi;
6202 | }
6203 |
6204 | proto_item *
6205 | proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6206 | int start, int length, int64_t value,
6207 | const char *format, ...)
6208 | {
6209 | proto_item *pi;
6210 | va_list ap;
6211 |
6212 | pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6213 | if (pi != tree) {
6214 | va_start(ap, format)__builtin_va_start(ap, format);
6215 | proto_tree_set_representation_value(pi, format, ap);
6216 | va_end(ap)__builtin_va_end(ap);
6217 | }
6218 |
6219 | return pi;
6220 | }
6221 |
6222 | /* Set the FT_INT{40,48,56,64} value */
6223 | static void
6224 | proto_tree_set_int64(field_info *fi, int64_t value)
6225 | {
6226 | const header_field_info *hfinfo;
6227 | uint64_t integer;
6228 | int no_of_bits;
6229 |
6230 | hfinfo = fi->hfinfo;
6231 | integer = value;
6232 |
6233 | if (hfinfo->bitmask) {
6234 | /* Mask out irrelevant portions */
6235 | integer &= hfinfo->bitmask;
6236 |
6237 | /* Shift bits */
6238 | integer >>= hfinfo_bitshift(hfinfo);
6239 |
6240 | no_of_bits = ws_count_ones(hfinfo->bitmask);
6241 | integer = ws_sign_ext64(integer, no_of_bits);
6242 |
6243 | FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset (hfinfo)) & 63) << 5)); } while(0);
6244 | 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);
6245 | }
6246 |
6247 | fvalue_set_sinteger64(fi->value, integer);
6248 | }
6249 |
6250 | proto_item *
6251 | proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6252 | int start, int length, int64_t value,
6253 | const char *format, ...)
6254 | {
6255 | proto_item *pi;
6256 | va_list ap;
6257 |
6258 | pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6259 | if (pi != tree) {
6260 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6260, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
6261 |
6262 | va_start(ap, format)__builtin_va_start(ap, format);
6263 | proto_tree_set_representation(pi, format, ap);
6264 | va_end(ap)__builtin_va_end(ap);
6265 | }
6266 |
6267 | return pi;
6268 | }
6269 |
6270 | /* Add a FT_EUI64 to a proto_tree */
6271 | proto_item *
6272 | proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6273 | int length, const uint64_t value)
6274 | {
6275 | proto_item *pi;
6276 | header_field_info *hfinfo;
6277 |
6278 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6279 |
6280 | 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", 6280 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6280, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6280, "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", 6280, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
6281 |
6282 | 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", 6282, ((hfinfo))->abbrev))));
6283 |
6284 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6285 | proto_tree_set_eui64(PNODE_FINFO(pi)((pi)->finfo), value);
6286 |
6287 | return pi;
6288 | }
6289 |
6290 | proto_item *
6291 | proto_tree_add_eui64_format_value(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 | va_start(ap, format)__builtin_va_start(ap, format);
6301 | proto_tree_set_representation_value(pi, format, ap);
6302 | va_end(ap)__builtin_va_end(ap);
6303 | }
6304 |
6305 | return pi;
6306 | }
6307 |
6308 | proto_item *
6309 | proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6310 | int start, int length, const uint64_t value,
6311 | const char *format, ...)
6312 | {
6313 | proto_item *pi;
6314 | va_list ap;
6315 |
6316 | pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6317 | if (pi != tree) {
6318 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6318, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
6319 |
6320 | va_start(ap, format)__builtin_va_start(ap, format);
6321 | proto_tree_set_representation(pi, format, ap);
6322 | va_end(ap)__builtin_va_end(ap);
6323 | }
6324 |
6325 | return pi;
6326 | }
6327 |
6328 | /* Set the FT_EUI64 value */
6329 | static void
6330 | proto_tree_set_eui64(field_info *fi, const uint64_t value)
6331 | {
6332 | uint8_t v[FT_EUI64_LEN8];
6333 | phtonu64(v, value);
6334 | fvalue_set_bytes_data(fi->value, v, FT_EUI64_LEN8);
6335 | }
6336 |
6337 | static void
6338 | proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding)
6339 | {
6340 | if (encoding)
6341 | {
6342 | proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
6343 | } else {
6344 | proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
6345 | }
6346 | }
6347 |
6348 | proto_item *
6349 | proto_tree_add_mac48_detail(const mac_hf_list_t *list_specific,
6350 | const mac_hf_list_t *list_generic,
6351 | int idx, tvbuff_t *tvb,
6352 | proto_tree *tree, int offset)
6353 | {
6354 | uint8_t addr[6];
6355 | const char *addr_name = NULL((void*)0);
6356 | const char *oui_name = NULL((void*)0);
6357 | proto_item *addr_item = NULL((void*)0);
6358 | proto_tree *addr_tree = NULL((void*)0);
6359 | proto_item *ret_val = NULL((void*)0);
6360 |
6361 | if (tree == NULL((void*)0) || list_specific == NULL((void*)0)) {
6362 | return NULL((void*)0);
6363 | }
6364 |
6365 | /* Resolve what we can of the address */
6366 | tvb_memcpy(tvb, addr, offset, sizeof addr);
6367 | if (list_specific->hf_addr_resolved || (list_generic && list_generic->hf_addr_resolved)) {
6368 | addr_name = get_ether_name(addr);
6369 | }
6370 | if (list_specific->hf_oui_resolved || (list_generic && list_generic->hf_oui_resolved)) {
6371 | oui_name = get_manuf_name_if_known(addr, sizeof(addr));
6372 | }
6373 |
6374 | /* Add the item for the specific address type */
6375 | ret_val = proto_tree_add_item(tree, *list_specific->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6376 | if (idx >= 0) {
6377 | addr_tree = proto_item_add_subtree(ret_val, idx);
6378 | }
6379 | else {
6380 | addr_tree = tree;
6381 | }
6382 |
6383 | if (list_specific->hf_addr_resolved != NULL((void*)0)) {
6384 | addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_addr_resolved,
6385 | tvb, offset, 6, addr_name);
6386 | proto_item_set_generated(addr_item);
6387 | proto_item_set_hidden(addr_item);
6388 | }
6389 |
6390 | if (list_specific->hf_oui != NULL((void*)0)) {
6391 | addr_item = proto_tree_add_item(addr_tree, *list_specific->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6392 | proto_item_set_generated(addr_item);
6393 | proto_item_set_hidden(addr_item);
6394 |
6395 | if (oui_name != NULL((void*)0) && list_specific->hf_oui_resolved != NULL((void*)0)) {
6396 | addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_oui_resolved, tvb, offset, 6, oui_name);
6397 | proto_item_set_generated(addr_item);
6398 | proto_item_set_hidden(addr_item);
6399 | }
6400 | }
6401 |
6402 | if (list_specific->hf_lg != NULL((void*)0)) {
6403 | proto_tree_add_item(addr_tree, *list_specific->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6404 | }
6405 | if (list_specific->hf_ig != NULL((void*)0)) {
6406 | proto_tree_add_item(addr_tree, *list_specific->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6407 | }
6408 |
6409 | /* Were we given a list for generic address fields? If not, stop here */
6410 | if (list_generic == NULL((void*)0)) {
6411 | return ret_val;
6412 | }
6413 |
6414 | addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6415 | proto_item_set_hidden(addr_item);
6416 |
6417 | if (list_generic->hf_addr_resolved != NULL((void*)0)) {
6418 | addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_addr_resolved,
6419 | tvb, offset, 6, addr_name);
6420 | proto_item_set_generated(addr_item);
6421 | proto_item_set_hidden(addr_item);
6422 | }
6423 |
6424 | if (list_generic->hf_oui != NULL((void*)0)) {
6425 | addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6426 | proto_item_set_generated(addr_item);
6427 | proto_item_set_hidden(addr_item);
6428 |
6429 | if (oui_name != NULL((void*)0) && list_generic->hf_oui_resolved != NULL((void*)0)) {
6430 | addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_oui_resolved, tvb, offset, 6, oui_name);
6431 | proto_item_set_generated(addr_item);
6432 | proto_item_set_hidden(addr_item);
6433 | }
6434 | }
6435 |
6436 | if (list_generic->hf_lg != NULL((void*)0)) {
6437 | addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6438 | proto_item_set_hidden(addr_item);
6439 | }
6440 | if (list_generic->hf_ig != NULL((void*)0)) {
6441 | addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6442 | proto_item_set_hidden(addr_item);
6443 | }
6444 | return ret_val;
6445 | }
6446 |
6447 | static proto_item *
6448 | proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo)
6449 | {
6450 | proto_node *pnode, *tnode, *sibling;
6451 | field_info *tfi;
6452 | unsigned depth = 1;
6453 |
6454 | ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6454, __func__, "assertion failed: %s", "tree" ); } while (0);
6455 |
6456 | /*
6457 | * Restrict our depth. proto_tree_traverse_pre_order and
6458 | * proto_tree_traverse_post_order (and possibly others) are recursive
6459 | * so we need to be mindful of our stack size.
6460 | */
6461 | if (tree->first_child == NULL((void*)0)) {
6462 | for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6463 | depth++;
6464 | if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6465 | 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__)), 6468)))
6466 | "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__)), 6468)))
6467 | 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__)), 6468)))
6468 | 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__)), 6468)));
6469 | }
6470 | }
6471 | }
6472 |
6473 | /*
6474 | * Make sure "tree" is ready to have subtrees under it, by
6475 | * checking whether it's been given an ett_ value.
6476 | *
6477 | * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6478 | * node of the protocol tree. That node is not displayed,
6479 | * so it doesn't need an ett_ value to remember whether it
6480 | * was expanded.
6481 | */
6482 | tnode = tree;
6483 | tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6484 | if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6485 | 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" , 6486)
6486 | 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" , 6486);
6487 | /* XXX - is it safe to continue here? */
6488 | }
6489 |
6490 | pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo-> pool)), sizeof(proto_node)));
6491 | PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = (( void*)0); pnode->next = ((void*)0);;
6492 | pnode->parent = tnode;
6493 | PNODE_HFINFO(pnode)((pnode)->hfinfo) = hfinfo;
6494 | PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0); // Faked
6495 | pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6496 |
6497 | if (tnode->last_child != NULL((void*)0)) {
6498 | sibling = tnode->last_child;
6499 | DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6499, "sibling->next == ((void*)0)" ))));
6500 | sibling->next = pnode;
6501 | } else
6502 | tnode->first_child = pnode;
6503 | tnode->last_child = pnode;
6504 |
6505 | /* We should not be adding a fake node for an interesting field */
6506 | 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", 6506, __func__, "assertion failed: %s" , "hfinfo->ref_type != HF_REF_TYPE_DIRECT && hfinfo->ref_type != HF_REF_TYPE_PRINT" ); } while (0);
6507 |
6508 | /* XXX - Should the proto_item have a header_field_info member, at least
6509 | * for faked items, to know what hfi was faked? (Some dissectors look at
6510 | * the tree items directly.)
6511 | */
6512 | return (proto_item *)pnode;
6513 | }
6514 |
6515 | /* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
6516 | static proto_item *
6517 | proto_tree_add_node(proto_tree *tree, field_info *fi)
6518 | {
6519 | proto_node *pnode, *tnode, *sibling;
6520 | field_info *tfi;
6521 | unsigned depth = 1;
6522 |
6523 | ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6523, __func__, "assertion failed: %s", "tree" ); } while (0);
6524 |
6525 | /*
6526 | * Restrict our depth. proto_tree_traverse_pre_order and
6527 | * proto_tree_traverse_post_order (and possibly others) are recursive
6528 | * so we need to be mindful of our stack size.
6529 | */
6530 | if (tree->first_child == NULL((void*)0)) {
6531 | for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6532 | depth++;
6533 | if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6534 | fvalue_free(fi->value);
6535 | fi->value = NULL((void*)0);
6536 | 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__)), 6539)))
6537 | "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__)), 6539)))
6538 | 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__)), 6539)))
6539 | 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__)), 6539)));
6540 | }
6541 | }
6542 | }
6543 |
6544 | /*
6545 | * Make sure "tree" is ready to have subtrees under it, by
6546 | * checking whether it's been given an ett_ value.
6547 | *
6548 | * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6549 | * node of the protocol tree. That node is not displayed,
6550 | * so it doesn't need an ett_ value to remember whether it
6551 | * was expanded.
6552 | */
6553 | tnode = tree;
6554 | tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6555 | if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6556 | /* Since we are not adding fi to a node, its fvalue won't get
6557 | * freed by proto_tree_free_node(), so free it now.
6558 | */
6559 | fvalue_free(fi->value);
6560 | fi->value = NULL((void*)0);
6561 | 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", 6562)
6562 | 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", 6562);
6563 | /* XXX - is it safe to continue here? */
6564 | }
6565 |
6566 | pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo-> pool)), sizeof(proto_node)));
6567 | PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = (( void*)0); pnode->next = ((void*)0);;
6568 | pnode->parent = tnode;
6569 | PNODE_HFINFO(pnode)((pnode)->hfinfo) = fi->hfinfo;
6570 | PNODE_FINFO(pnode)((pnode)->finfo) = fi;
6571 | pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6572 |
6573 | if (tnode->last_child != NULL((void*)0)) {
6574 | sibling = tnode->last_child;
6575 | DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6575, "sibling->next == ((void*)0)" ))));
6576 | sibling->next = pnode;
6577 | } else
6578 | tnode->first_child = pnode;
6579 | tnode->last_child = pnode;
6580 |
6581 | tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
6582 |
6583 | return (proto_item *)pnode;
6584 | }
6585 |
6586 |
6587 | /* Generic way to allocate field_info and add to proto_tree.
6588 | * Sets *pfi to address of newly-allocated field_info struct */
6589 | static proto_item *
6590 | proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, int start,
6591 | int *length)
6592 | {
6593 | proto_item *pi;
6594 | field_info *fi;
6595 | int item_length;
6596 |
6597 | get_hfi_length(hfinfo, tvb, start, length, &item_length, ENC_NA0x00000000);
6598 | fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6599 | pi = proto_tree_add_node(tree, fi);
6600 |
6601 | return pi;
6602 | }
6603 |
6604 |
6605 | static void
6606 | get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start, int *length,
6607 | int *item_length, const unsigned encoding)
6608 | {
6609 | int length_remaining;
6610 |
6611 | /*
6612 | * We only allow a null tvbuff if the item has a zero length,
6613 | * i.e. if there's no data backing it.
6614 | */
6615 | 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", 6615, "tvb != ((void*)0) || *length == 0" ))));
6616 |
6617 | /*
6618 | * XXX - in some protocols, there are 32-bit unsigned length
6619 | * fields, so lengths in protocol tree and tvbuff routines
6620 | * should really be unsigned. We should have, for those
6621 | * field types for which "to the end of the tvbuff" makes sense,
6622 | * additional routines that take no length argument and
6623 | * add fields that run to the end of the tvbuff.
6624 | */
6625 | if (*length == -1) {
6626 | /*
6627 | * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING,
6628 | * FT_STRINGZPAD, and FT_STRINGZTRUNC fields, a length
6629 | * of -1 means "set the length to what remains in the
6630 | * tvbuff".
6631 | *
6632 | * The assumption is either that
6633 | *
6634 | * 1) the length of the item can only be determined
6635 | * by dissection (typically true of items with
6636 | * subitems, which are probably FT_NONE or
6637 | * FT_PROTOCOL)
6638 | *
6639 | * or
6640 | *
6641 | * 2) if the tvbuff is "short" (either due to a short
6642 | * snapshot length or due to lack of reassembly of
6643 | * fragments/segments/whatever), we want to display
6644 | * what's available in the field (probably FT_BYTES
6645 | * or FT_STRING) and then throw an exception later
6646 | *
6647 | * or
6648 | *
6649 | * 3) the field is defined to be "what's left in the
6650 | * packet"
6651 | *
6652 | * so we set the length to what remains in the tvbuff so
6653 | * that, if we throw an exception while dissecting, it
6654 | * has what is probably the right value.
6655 | *
6656 | * For FT_STRINGZ, it means "the string is null-terminated,
6657 | * not null-padded; set the length to the actual length
6658 | * of the string", and if the tvbuff if short, we just
6659 | * throw an exception.
6660 | *
6661 | * For ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC|ENC_VARIANT_ZIGZAG|ENC_VARINT_SDNV,
6662 | * it means "find the end of the string",
6663 | * and if the tvbuff if short, we just throw an exception.
6664 | *
6665 | * It's not valid for any other type of field. For those
6666 | * fields, we treat -1 the same way we treat other
6667 | * negative values - we assume the length is a Really
6668 | * Big Positive Number, and throw a ReportedBoundsError
6669 | * exception, under the assumption that the Really Big
6670 | * Length would run past the end of the packet.
6671 | */
6672 | 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 )))) {
6673 | if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
6674 | /*
6675 | * Leave the length as -1, so our caller knows
6676 | * it was -1.
6677 | */
6678 | *item_length = *length;
6679 | return;
6680 | } else if (encoding & ENC_VARINT_QUIC0x00000004) {
6681 | switch (tvb_get_uint8(tvb, start) >> 6)
6682 | {
6683 | case 0: /* 0b00 => 1 byte length (6 bits Usable) */
6684 | *item_length = 1;
6685 | break;
6686 | case 1: /* 0b01 => 2 bytes length (14 bits Usable) */
6687 | *item_length = 2;
6688 | break;
6689 | case 2: /* 0b10 => 4 bytes length (30 bits Usable) */
6690 | *item_length = 4;
6691 | break;
6692 | case 3: /* 0b11 => 8 bytes length (62 bits Usable) */
6693 | *item_length = 8;
6694 | break;
6695 | }
6696 | }
6697 | }
6698 |
6699 | switch (hfinfo->type) {
6700 |
6701 | case FT_PROTOCOL:
6702 | case FT_NONE:
6703 | case FT_BYTES:
6704 | case FT_STRING:
6705 | case FT_STRINGZPAD:
6706 | case FT_STRINGZTRUNC:
6707 | /*
6708 | * We allow FT_PROTOCOLs to be zero-length -
6709 | * for example, an ONC RPC NULL procedure has
6710 | * neither arguments nor reply, so the
6711 | * payload for that protocol is empty.
6712 | *
6713 | * We also allow the others to be zero-length -
6714 | * because that's the way the code has been for a
6715 | * long, long time.
6716 | *
6717 | * However, we want to ensure that the start
6718 | * offset is not *past* the byte past the end
6719 | * of the tvbuff: we throw an exception in that
6720 | * case.
6721 | */
6722 | *length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
6723 | DISSECTOR_ASSERT(*length >= 0)((void) ((*length >= 0) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6723, "*length >= 0" ))));
6724 | break;
6725 |
6726 | case FT_STRINGZ:
6727 | /*
6728 | * Leave the length as -1, so our caller knows
6729 | * it was -1.
6730 | */
6731 | break;
6732 |
6733 | default:
6734 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6735 | DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\"" , "epan/proto.c", 6735));
6736 | }
6737 | *item_length = *length;
6738 | } else {
6739 | *item_length = *length;
6740 | if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6741 | /*
6742 | * These types are for interior nodes of the
6743 | * tree, and don't have data associated with
6744 | * them; if the length is negative (XXX - see
6745 | * above) or goes past the end of the tvbuff,
6746 | * cut it short at the end of the tvbuff.
6747 | * That way, if this field is selected in
6748 | * Wireshark, we don't highlight stuff past
6749 | * the end of the data.
6750 | */
6751 | /* XXX - what to do, if we don't have a tvb? */
6752 | if (tvb) {
6753 | length_remaining = tvb_captured_length_remaining(tvb, start);
6754 | if (*item_length < 0 ||
6755 | (*item_length > 0 &&
6756 | (length_remaining < *item_length)))
6757 | *item_length = length_remaining;
6758 | }
6759 | }
6760 | if (*item_length < 0) {
6761 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6762 | }
6763 | }
6764 | }
6765 |
6766 | static int
6767 | get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start,
6768 | int length, unsigned item_length, const int encoding)
6769 | {
6770 | uint32_t n;
6771 |
6772 | /*
6773 | * We need to get the correct item length here.
6774 | * That's normally done by proto_tree_new_item(),
6775 | * but we won't be calling it.
6776 | */
6777 | switch (hfinfo->type) {
6778 |
6779 | case FT_NONE:
6780 | case FT_PROTOCOL:
6781 | case FT_BYTES:
6782 | /*
6783 | * The length is the specified length.
6784 | */
6785 | break;
6786 |
6787 | case FT_UINT_BYTES:
6788 | n = get_uint_value(NULL((void*)0), tvb, start, length, encoding);
6789 | item_length += n;
6790 | if ((int)item_length < length) {
6791 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6792 | }
6793 | break;
6794 |
6795 | /* XXX - make these just FT_UINT? */
6796 | case FT_UINT8:
6797 | case FT_UINT16:
6798 | case FT_UINT24:
6799 | case FT_UINT32:
6800 | case FT_UINT40:
6801 | case FT_UINT48:
6802 | case FT_UINT56:
6803 | case FT_UINT64:
6804 | /* XXX - make these just FT_INT? */
6805 | case FT_INT8:
6806 | case FT_INT16:
6807 | case FT_INT24:
6808 | case FT_INT32:
6809 | case FT_INT40:
6810 | case FT_INT48:
6811 | case FT_INT56:
6812 | case FT_INT64:
6813 | if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
6814 | if (length < -1) {
6815 | report_type_length_mismatch(NULL((void*)0), "a FT_[U]INT", length, true1);
6816 | }
6817 | if (length == -1) {
6818 | uint64_t dummy;
6819 | /* This can throw an exception */
6820 | /* XXX - do this without fetching the varint? */
6821 | length = tvb_get_varint(tvb, start, FT_VARINT_MAX_LEN10, &dummy, encoding);
6822 | if (length == 0) {
6823 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6824 | }
6825 | }
6826 | item_length = length;
6827 | break;
6828 | }
6829 |
6830 | /*
6831 | * The length is the specified length.
6832 | */
6833 | break;
6834 |
6835 | case FT_BOOLEAN:
6836 | case FT_CHAR:
6837 | case FT_IPv4:
6838 | case FT_IPXNET:
6839 | case FT_IPv6:
6840 | case FT_FCWWN:
6841 | case FT_AX25:
6842 | case FT_VINES:
6843 | case FT_ETHER:
6844 | case FT_EUI64:
6845 | case FT_GUID:
6846 | case FT_OID:
6847 | case FT_REL_OID:
6848 | case FT_SYSTEM_ID:
6849 | case FT_FLOAT:
6850 | case FT_DOUBLE:
6851 | case FT_STRING:
6852 | /*
6853 | * The length is the specified length.
6854 | */
6855 | break;
6856 |
6857 | case FT_STRINGZ:
6858 | if (length < -1) {
6859 | report_type_length_mismatch(NULL((void*)0), "a string", length, true1);
6860 | }
6861 | if (length == -1) {
6862 | /* This can throw an exception */
6863 | /* XXX - do this without fetching the string? Depends on
6864 | * encoding, so we probably need a new function. */
6865 | wmem_free(NULL((void*)0), tvb_get_stringz_enc(NULL((void*)0), tvb, start, (unsigned*)&length, encoding));
6866 | }
6867 | item_length = length;
6868 | break;
6869 |
6870 | case FT_UINT_STRING:
6871 | n = get_uint_value(NULL((void*)0), tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
6872 | item_length += n;
6873 | if ((int)item_length < length) {
6874 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6875 | }
6876 | break;
6877 |
6878 | case FT_STRINGZPAD:
6879 | case FT_STRINGZTRUNC:
6880 | case FT_ABSOLUTE_TIME:
6881 | case FT_RELATIVE_TIME:
6882 | case FT_IEEE_11073_SFLOAT:
6883 | case FT_IEEE_11073_FLOAT:
6884 | /*
6885 | * The length is the specified length.
6886 | */
6887 | break;
6888 |
6889 | default:
6890 | 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 ))
6891 | 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 ))
6892 | 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 ))
6893 | 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 ));
6894 | break;
6895 | }
6896 | return item_length;
6897 | }
6898 |
6899 | // This was arbitrarily chosen, but if you're adding 50K items to the tree
6900 | // without advancing the offset you should probably take a long, hard look
6901 | // at what you're doing.
6902 | // We *could* make this a configurable option, but I (Gerald) would like to
6903 | // avoid adding yet another nerd knob.
6904 | # define PROTO_TREE_MAX_IDLE50000 50000
6905 | static field_info *
6906 | new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
6907 | const int start, const int item_length)
6908 | {
6909 | field_info *fi;
6910 |
6911 | FIELD_INFO_NEW(PNODE_POOL(tree), fi)fi = ((field_info*)wmem_alloc((((tree)->tree_data->pinfo ->pool)), sizeof(field_info)));
6912 |
6913 | fi->hfinfo = hfinfo;
6914 | fi->start = start;
6915 | fi->start += (tvb)?tvb_raw_offset(tvb):0;
6916 | /* add the data source tvbuff */
6917 | fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL((void*)0);
6918 |
6919 | // If our start offset hasn't advanced after adding many items it probably
6920 | // means we're in a large or infinite loop.
6921 | if (fi->start > 0) {
6922 | if (fi->ds_tvb == PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb && fi->start <= PTREE_DATA(tree)((tree)->tree_data)->max_start) {
6923 | PTREE_DATA(tree)((tree)->tree_data)->start_idle_count++;
6924 | 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", 6924, "((tree)->tree_data)->start_idle_count < 50000" , fi->hfinfo->abbrev))));
6925 | } else {
6926 | PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb = fi->ds_tvb;
6927 | PTREE_DATA(tree)((tree)->tree_data)->max_start = fi->start;
6928 | PTREE_DATA(tree)((tree)->tree_data)->start_idle_count = 0;
6929 | }
6930 | }
6931 | fi->length = item_length;
6932 | fi->tree_type = -1;
6933 | fi->flags = 0;
6934 | if (!PTREE_DATA(tree)((tree)->tree_data)->visible) {
6935 | /* If the tree is not visible, set the item hidden, unless we
6936 | * need the representation or length and can't fake them.
6937 | */
6938 | if (hfinfo->ref_type != HF_REF_TYPE_PRINT && (hfinfo->type != FT_PROTOCOL || PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) {
6939 | FI_SET_FLAG(fi, FI_HIDDEN)do { if (fi) (fi)->flags = (fi)->flags | (0x00000001); } while(0);
6940 | }
6941 | }
6942 | fi->value = fvalue_new(fi->hfinfo->type);
6943 | fi->rep = NULL((void*)0);
6944 |
6945 | fi->appendix_start = 0;
6946 | fi->appendix_length = 0;
6947 |
6948 | fi->total_layer_num = tree->tree_data->pinfo->curr_layer_num;
6949 | fi->proto_layer_num = tree->tree_data->pinfo->curr_proto_layer_num;
6950 |
6951 | return fi;
6952 | }
6953 |
6954 | static size_t proto_find_value_pos(const header_field_info *hfinfo, const char *representation)
6955 | {
6956 | if (hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000) {
6957 | return 0;
6958 | }
6959 |
6960 | /* Search for field name */
6961 | char *ptr = strstr(representation, hfinfo->name);
6962 | if (!ptr) {
6963 | return 0;
6964 | }
6965 |
6966 | /* Check if field name ends with the ": " delimiter */
6967 | ptr += strlen(hfinfo->name);
6968 | if (strncmp(ptr, ": ", 2) == 0) {
6969 | ptr += 2;
6970 | }
6971 |
6972 | /* Return offset to after field name */
6973 | return ptr - representation;
6974 | }
6975 |
6976 | static size_t label_find_name_pos(const item_label_t *rep)
6977 | {
6978 | size_t name_pos = 0;
6979 |
6980 | /* If the value_pos is too small or too large, we can't find the expected format */
6981 | if (rep->value_pos <= 2 || rep->value_pos >= sizeof(rep->representation)) {
6982 | return 0;
6983 | }
6984 |
6985 | /* Check if the format looks like "label: value", then set name_pos before ':'. */
6986 | if (rep->representation[rep->value_pos-2] == ':') {
6987 | name_pos = rep->value_pos - 2;
6988 | }
6989 |
6990 | return name_pos;
6991 | }
6992 |
6993 | /* If the protocol tree is to be visible, set the representation of a
6994 | proto_tree entry with the name of the field for the item and with
6995 | the value formatted with the supplied printf-style format and
6996 | argument list. */
6997 | static void
6998 | proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
6999 | {
7000 | ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 7000, __func__, "assertion failed: %s", "pi" ); } while (0);
7001 |
7002 | /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
7003 | * items string representation */
7004 | if (PTREE_DATA(pi)((pi)->tree_data)->visible || !proto_item_is_hidden(pi)) {
7005 | size_t name_pos, ret = 0;
7006 | char *str;
7007 | field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7008 | const header_field_info *hf;
7009 |
7010 | DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 7010, "fi"))));
7011 |
7012 | hf = fi->hfinfo;
7013 |
7014 | 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;;
7015 | 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)))) {
7016 | uint64_t val;
7017 | char *p;
7018 |
7019 | 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))
7020 | val = fvalue_get_uinteger(fi->value);
7021 | else
7022 | val = fvalue_get_uinteger64(fi->value);
7023 |
7024 | val <<= hfinfo_bitshift(hf);
7025 |
7026 | p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
7027 | ret = (p - fi->rep->representation);
7028 | }
7029 |
7030 | /* put in the hf name */
7031 | 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);
7032 |
7033 | ret = label_concat(fi->rep->representation, ret, (const uint8_t*)": ")ws_label_strcpy(fi->rep->representation, 240, ret, (const uint8_t*)": ", 0);
7034 | /* If possible, Put in the value of the string */
7035 | str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7036 | 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" , 7036, __func__, str, -1, __uni_endptr); } } while (0); } } while (0);
7037 | fi->rep->value_pos = ret;
7038 | ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, ret, (const uint8_t*)str, 0);
7039 | if (ret >= ITEM_LABEL_LENGTH240) {
7040 | /* Uh oh, we don't have enough room. Tell the user
7041 | * that the field is truncated.
7042 | */
7043 | label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7044 | }
7045 | fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7046 | }
7047 | }
7048 |
7049 | /* If the protocol tree is to be visible, set the representation of a
7050 | proto_tree entry with the representation formatted with the supplied
7051 | printf-style format and argument list. */
7052 | static void
7053 | proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
7054 | {
7055 | size_t ret; /*tmp return value */
7056 | char *str;
7057 | field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7058 |
7059 | DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 7059, "fi"))));
7060 |
7061 | if (!proto_item_is_hidden(pi)) {
7062 | 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;;
7063 |
7064 | str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7065 | 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" , 7065, __func__, str, -1, __uni_endptr); } } while (0); } } while (0);
7066 | fi->rep->value_pos = proto_find_value_pos(fi->hfinfo, str);
7067 | ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, (const uint8_t*)str, 0);
7068 | if (ret >= ITEM_LABEL_LENGTH240) {
7069 | /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7070 | size_t name_pos = label_find_name_pos(fi->rep);
7071 | label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7072 | }
7073 | fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7074 | }
7075 | }
7076 |
7077 | static int
7078 | proto_strlcpy(char *dest, const char *src, size_t dest_size)
7079 | {
7080 | if (dest_size == 0) return 0;
7081 |
7082 | size_t res = g_strlcpy(dest, src, dest_size);
7083 |
7084 | /* At most dest_size - 1 characters will be copied
7085 | * (unless dest_size is 0). */
7086 | if (res >= dest_size)
7087 | res = dest_size - 1;
7088 | return (int) res;
7089 | }
7090 |
7091 | static header_field_info *
7092 | hfinfo_same_name_get_prev(const header_field_info *hfinfo)
7093 | {
7094 | header_field_info *dup_hfinfo;
7095 |
7096 | if (hfinfo->same_name_prev_id == -1)
7097 | return NULL((void*)0);
7098 | 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", 7098 , __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", 7098, "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", 7098, "gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)" , "Unregistered hf!")))) ; dup_hfinfo = gpa_hfinfo.hfi[hfinfo ->same_name_prev_id];;
7099 | return dup_hfinfo;
7100 | }
7101 |
7102 | static void
7103 | hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
7104 | {
7105 | g_free(last_field_name);
7106 | last_field_name = NULL((void*)0);
7107 |
7108 | if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
7109 | /* No hfinfo with the same name */
7110 | wmem_map_remove(gpa_name_map, hfinfo->abbrev);
7111 | return;
7112 | }
7113 |
7114 | if (hfinfo->same_name_next) {
7115 | hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
7116 | }
7117 |
7118 | if (hfinfo->same_name_prev_id != -1) {
7119 | header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
7120 | same_name_prev->same_name_next = hfinfo->same_name_next;
7121 | if (!hfinfo->same_name_next) {
7122 | /* It's always the latest added hfinfo which is stored in gpa_name_map */
7123 | wmem_map_insert(gpa_name_map, (void *) (same_name_prev->abbrev), same_name_prev);
7124 | }
7125 | }
7126 | }
7127 |
7128 | int
7129 | proto_item_fill_display_label(const field_info *finfo, char *display_label_str, const int label_str_size)
7130 | {
7131 | const header_field_info *hfinfo = finfo->hfinfo;
7132 | int label_len = 0;
7133 | char *tmp_str;
7134 | const char *str;
7135 | const uint8_t *bytes;
7136 | uint32_t number;
7137 | uint64_t number64;
7138 | const char *hf_str_val;
7139 | char number_buf[NUMBER_LABEL_LENGTH80];
7140 | const char *number_out;
7141 | address addr;
7142 | const ipv4_addr_and_mask *ipv4;
7143 | const ipv6_addr_and_prefix *ipv6;
7144 |
7145 | switch (hfinfo->type) {
7146 |
7147 | case FT_NONE:
7148 | case FT_PROTOCOL:
7149 | return proto_strlcpy(display_label_str, UTF8_CHECK_MARK"\u2713", label_str_size);
7150 |
7151 | case FT_UINT_BYTES:
7152 | case FT_BYTES:
7153 | tmp_str = format_bytes_hfinfo_maxlen(NULL((void*)0),
7154 | hfinfo,
7155 | fvalue_get_bytes_data(finfo->value),
7156 | (unsigned)fvalue_length2(finfo->value),
7157 | label_str_size);
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 | case FT_ABSOLUTE_TIME:
7163 | {
7164 | const nstime_t *value = fvalue_get_time(finfo->value);
7165 | int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
7166 | if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_COLUMN) {
7167 | flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
7168 | }
7169 | if (hfinfo->strings) {
7170 | const char *time_string = try_time_val_to_str(value, (const time_value_string*)hfinfo->strings);
7171 | if (time_string != NULL((void*)0)) {
7172 | label_len = proto_strlcpy(display_label_str, time_string, label_str_size);
7173 | break;
7174 | }
7175 | }
7176 | tmp_str = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
7177 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7178 | wmem_free(NULL((void*)0), tmp_str);
7179 | break;
7180 | }
7181 |
7182 | case FT_RELATIVE_TIME:
7183 | tmp_str = rel_time_to_secs_str(NULL((void*)0), fvalue_get_time(finfo->value));
7184 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7185 | wmem_free(NULL((void*)0), tmp_str);
7186 | break;
7187 |
7188 | case FT_BOOLEAN:
7189 | number64 = fvalue_get_uinteger64(finfo->value);
7190 | label_len = proto_strlcpy(display_label_str,
7191 | tfs_get_string(!!number64, hfinfo->strings), label_str_size);
7192 | break;
7193 |
7194 | case FT_CHAR:
7195 | number = fvalue_get_uinteger(finfo->value);
7196 |
7197 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7198 | char tmp[ITEM_LABEL_LENGTH240];
7199 | custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7200 |
7201 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 7201, "fmtfunc"))));
7202 | fmtfunc(tmp, number);
7203 |
7204 | label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7205 |
7206 | } else if (hfinfo->strings) {
7207 | number_out = hf_try_val_to_str(number, hfinfo);
7208 |
7209 | if (!number_out) {
7210 | number_out = hfinfo_char_value_format_display(BASE_HEX, number_buf, number);
7211 | }
7212 |
7213 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7214 |
7215 | } else {
7216 | number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
7217 |
7218 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7219 | }
7220 |
7221 | break;
7222 |
7223 | /* XXX - make these just FT_NUMBER? */
7224 | case FT_INT8:
7225 | case FT_INT16:
7226 | case FT_INT24:
7227 | case FT_INT32:
7228 | case FT_UINT8:
7229 | case FT_UINT16:
7230 | case FT_UINT24:
7231 | case FT_UINT32:
7232 | case FT_FRAMENUM:
7233 | hf_str_val = NULL((void*)0);
7234 | 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 )) ?
7235 | (uint32_t) fvalue_get_sinteger(finfo->value) :
7236 | fvalue_get_uinteger(finfo->value);
7237 |
7238 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7239 | char tmp[ITEM_LABEL_LENGTH240];
7240 | custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7241 |
7242 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 7242, "fmtfunc"))));
7243 | fmtfunc(tmp, number);
7244 |
7245 | label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7246 |
7247 | } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
7248 | if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7249 | number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
7250 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7251 | hf_str_val = hf_try_val_to_str(number, hfinfo);
7252 | label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7253 | } else {
7254 | number_out = hf_try_val_to_str(number, hfinfo);
7255 |
7256 | if (!number_out) {
7257 | number_out = hfinfo_number_value_format_display(hfinfo, hfinfo->display, number_buf, number);
7258 | }
7259 |
7260 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7261 | }
7262 | } else {
7263 | number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
7264 |
7265 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7266 | }
7267 |
7268 | break;
7269 |
7270 | case FT_INT40:
7271 | case FT_INT48:
7272 | case FT_INT56:
7273 | case FT_INT64:
7274 | case FT_UINT40:
7275 | case FT_UINT48:
7276 | case FT_UINT56:
7277 | case FT_UINT64:
7278 | hf_str_val = NULL((void*)0);
7279 | 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 )) ?
7280 | (uint64_t) fvalue_get_sinteger64(finfo->value) :
7281 | fvalue_get_uinteger64(finfo->value);
7282 |
7283 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7284 | char tmp[ITEM_LABEL_LENGTH240];
7285 | custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
7286 |
7287 | DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug( "%s:%u: failed assertion \"%s\"", "epan/proto.c", 7287, "fmtfunc64" ))));
7288 | fmtfunc64(tmp, number64);
7289 |
7290 | label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7291 | } else if (hfinfo->strings) {
7292 | if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7293 | number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
7294 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7295 | hf_str_val = hf_try_val64_to_str(number64, hfinfo);
7296 | label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7297 | } else {
7298 | number_out = hf_try_val64_to_str(number64, hfinfo);
7299 |
7300 | if (!number_out)
7301 | number_out = hfinfo_number_value_format_display64(hfinfo, hfinfo->display, number_buf, number64);
7302 |
7303 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7304 | }
7305 | } else {
7306 | number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
7307 |
7308 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7309 | }
7310 |
7311 | break;
7312 |
7313 | case FT_EUI64:
7314 | set_address (&addr, AT_EUI64, EUI64_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7315 | tmp_str = address_to_display(NULL((void*)0), &addr);
7316 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7317 | wmem_free(NULL((void*)0), tmp_str);
7318 | break;
7319 |
7320 | case FT_IPv4:
7321 | ipv4 = fvalue_get_ipv4(finfo->value);
7322 | //XXX: Should we ignore the mask?
7323 | set_address_ipv4(&addr, ipv4);
7324 | tmp_str = address_to_display(NULL((void*)0), &addr);
7325 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7326 | wmem_free(NULL((void*)0), tmp_str);
7327 | free_address(&addr);
7328 | break;
7329 |
7330 | case FT_IPv6:
7331 | ipv6 = fvalue_get_ipv6(finfo->value);
7332 | set_address_ipv6(&addr, ipv6);
7333 | tmp_str = address_to_display(NULL((void*)0), &addr);
7334 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7335 | wmem_free(NULL((void*)0), tmp_str);
7336 | free_address(&addr);
7337 | break;
7338 |
7339 | case FT_FCWWN:
7340 | set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7341 | tmp_str = address_to_display(NULL((void*)0), &addr);
7342 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7343 | wmem_free(NULL((void*)0), tmp_str);
7344 | break;
7345 |
7346 | case FT_ETHER:
7347 | set_address (&addr, AT_ETHER, FT_ETHER_LEN6, fvalue_get_bytes_data(finfo->value));
7348 | tmp_str = address_to_display(NULL((void*)0), &addr);
7349 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7350 | wmem_free(NULL((void*)0), tmp_str);
7351 | break;
7352 |
7353 | case FT_GUID:
7354 | tmp_str = guid_to_str(NULL((void*)0), fvalue_get_guid(finfo->value));
7355 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7356 | wmem_free(NULL((void*)0), tmp_str);
7357 | break;
7358 |
7359 | case FT_REL_OID:
7360 | bytes = fvalue_get_bytes_data(finfo->value);
7361 | tmp_str = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7362 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7363 | wmem_free(NULL((void*)0), tmp_str);
7364 | break;
7365 |
7366 | case FT_OID:
7367 | bytes = fvalue_get_bytes_data(finfo->value);
7368 | tmp_str = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7369 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7370 | wmem_free(NULL((void*)0), tmp_str);
7371 | break;
7372 |
7373 | case FT_SYSTEM_ID:
7374 | bytes = fvalue_get_bytes_data(finfo->value);
7375 | tmp_str = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7376 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7377 | wmem_free(NULL((void*)0), tmp_str);
7378 | break;
7379 |
7380 | case FT_FLOAT:
7381 | case FT_DOUBLE:
7382 | label_len = (int)fill_display_label_float(finfo, display_label_str, label_str_size);
7383 | break;
7384 |
7385 | case FT_IEEE_11073_SFLOAT:
7386 | case FT_IEEE_11073_FLOAT:
7387 | label_len = (int)fill_display_label_ieee_11073_float(finfo, display_label_str, label_str_size);
7388 | break;
7389 |
7390 | case FT_STRING:
7391 | case FT_STRINGZ:
7392 | case FT_UINT_STRING:
7393 | case FT_STRINGZPAD:
7394 | case FT_STRINGZTRUNC:
7395 | str = fvalue_get_string(finfo->value);
7396 | label_len = (int)ws_label_strcpy(display_label_str, label_str_size, 0, (const uint8_t*)str, label_strcat_flags(hfinfo));
7397 | if (label_len >= label_str_size) {
7398 | /* Truncation occurred. Get the real length
7399 | * copied (not including '\0') */
7400 | label_len = label_str_size ? label_str_size - 1 : 0;
7401 | }
7402 | break;
7403 |
7404 | default:
7405 | /* First try ftype string representation */
7406 | tmp_str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DISPLAY, hfinfo->display);
7407 | if (!tmp_str) {
7408 | /* Default to show as bytes */
7409 | bytes = fvalue_get_bytes_data(finfo->value);
7410 | tmp_str = bytes_to_str(NULL, bytes, fvalue_length2(finfo->value))bytes_to_str_maxlen(((void*)0), bytes, fvalue_length2(finfo-> value), 36);
7411 | }
7412 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7413 | wmem_free(NULL((void*)0), tmp_str);
7414 | break;
7415 | }
7416 | return label_len;
7417 | }
7418 |
7419 | const char *
7420 | proto_custom_set(proto_tree* tree, GSList *field_ids, int occurrence, bool_Bool display_details,
7421 | char *result, char *expr, const int size)
7422 | {
7423 | int len, prev_len, last, i, offset_r = 0, offset_e = 0;
7424 | GPtrArray *finfos;
7425 | field_info *finfo = NULL((void*)0);
7426 | header_field_info* hfinfo;
7427 | const char *abbrev = NULL((void*)0);
7428 |
7429 | char *str;
7430 | col_custom_t *field_idx;
7431 | int field_id;
7432 | int ii = 0;
7433 |
7434 | ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7434, __func__, "assertion failed: %s" , "field_ids != ((void*)0)"); } while (0);
7435 | while ((field_idx = (col_custom_t *) g_slist_nth_data(field_ids, ii++))) {
7436 | field_id = field_idx->field_id;
7437 | if (field_id == 0) {
7438 | GPtrArray *fvals = NULL((void*)0);
7439 | bool_Bool passed = dfilter_apply_full(field_idx->dfilter, tree, &fvals);
7440 | if (fvals != NULL((void*)0)) {
7441 |
7442 | // XXX - Handling occurrences is unusual when more
7443 | // than one field is involved, e.g. there's four
7444 | // results for tcp.port + tcp.port. We may really
7445 | // want to apply it to the operands, not the output.
7446 | // Note that occurrences are not quite the same as
7447 | // the layer operator (should the grammar support
7448 | // both?)
7449 | /* Calculate single index or set outer boundaries */
7450 | len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7451 | if (occurrence < 0) {
7452 | i = occurrence + len;
7453 | last = i;
7454 | } else if (occurrence > 0) {
7455 | i = occurrence - 1;
7456 | last = i;
7457 | } else {
7458 | i = 0;
7459 | last = len - 1;
7460 | }
7461 | if (i < 0 || i >= len) {
7462 | g_ptr_array_unref(fvals);
7463 | continue;
7464 | }
7465 | for (; i <= last; i++) {
7466 | /* XXX - We could have a "resolved" result
7467 | * for types where the value depends only
7468 | * on the type, e.g. FT_IPv4, and not on
7469 | * hfinfo->strings. Supporting the latter
7470 | * requires knowing which hfinfo matched
7471 | * if there are multiple with the same
7472 | * abbreviation. In any case, we need to
7473 | * know the expected return type of the
7474 | * field expression.
7475 | */
7476 | str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DISPLAY, BASE_NONE);
7477 | if (offset_r && (offset_r < (size - 1)))
7478 | result[offset_r++] = ',';
7479 | if (offset_e && (offset_e < (size - 1)))
7480 | expr[offset_e++] = ',';
7481 | offset_r += proto_strlcpy(result+offset_r, str, size-offset_r);
7482 | // col_{add,append,set}_* calls ws_label_strcpy
7483 | offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7484 |
7485 | g_free(str);
7486 | }
7487 | g_ptr_array_unref(fvals);
7488 | } else if (passed) {
7489 | // XXX - Occurrence doesn't make sense for a test
7490 | // output, it should be applied to the operands.
7491 | if (offset_r && (offset_r < (size - 1)))
7492 | result[offset_r++] = ',';
7493 | if (offset_e && (offset_e < (size - 1)))
7494 | expr[offset_e++] = ',';
7495 | /* Prevent multiple check marks */
7496 | if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7497 | offset_r += proto_strlcpy(result+offset_r, UTF8_CHECK_MARK"\u2713", size-offset_r);
7498 | } else {
7499 | result[--offset_r] = '\0'; /* Remove the added trailing ',' */
7500 | }
7501 | if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7502 | offset_e += proto_strlcpy(expr+offset_e, UTF8_CHECK_MARK"\u2713", size-offset_e);
7503 | } else {
7504 | expr[--offset_e] = '\0'; /* Remove the added trailing ',' */
7505 | }
7506 | }
7507 | continue;
7508 | }
7509 | 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", 7509 , __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", 7509, "(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", 7509, "gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];;
7510 |
7511 | /* do we need to rewind ? */
7512 | if (!hfinfo)
7513 | return "";
7514 |
7515 | if (occurrence < 0) {
7516 | /* Search other direction */
7517 | while (hfinfo->same_name_prev_id != -1) {
7518 | 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", 7518 , __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", 7518, "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", 7518, "gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo-> same_name_prev_id];;
7519 | }
7520 | }
7521 |
7522 | prev_len = 0; /* Reset handled occurrences */
7523 |
7524 | while (hfinfo) {
7525 | finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
7526 |
7527 | if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7528 | if (occurrence < 0) {
7529 | hfinfo = hfinfo->same_name_next;
7530 | } else {
7531 | hfinfo = hfinfo_same_name_get_prev(hfinfo);
7532 | }
7533 | continue;
7534 | }
7535 |
7536 | /* Are there enough occurrences of the field? */
7537 | if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7538 | if (occurrence < 0) {
7539 | hfinfo = hfinfo->same_name_next;
7540 | } else {
7541 | hfinfo = hfinfo_same_name_get_prev(hfinfo);
7542 | }
7543 | prev_len += len;
7544 | continue;
7545 | }
7546 |
7547 | /* Calculate single index or set outer boundaries */
7548 | if (occurrence < 0) {
7549 | i = occurrence + len + prev_len;
7550 | last = i;
7551 | } else if (occurrence > 0) {
7552 | i = occurrence - 1 - prev_len;
7553 | last = i;
7554 | } else {
7555 | i = 0;
7556 | last = len - 1;
7557 | }
7558 |
7559 | prev_len += len; /* Count handled occurrences */
7560 |
7561 | while (i <= last) {
7562 | finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7563 |
7564 | if (offset_r && (offset_r < (size - 1)))
7565 | result[offset_r++] = ',';
7566 |
7567 | if (display_details) {
7568 | char representation[ITEM_LABEL_LENGTH240];
7569 | size_t offset = 0;
7570 |
7571 | if (finfo->rep && finfo->rep->value_len) {
7572 | g_strlcpy(representation, &finfo->rep->representation[finfo->rep->value_pos],
7573 | MIN(finfo->rep->value_len + 1, ITEM_LABEL_LENGTH)(((finfo->rep->value_len + 1) < (240)) ? (finfo-> rep->value_len + 1) : (240)));
7574 | } else {
7575 | proto_item_fill_label(finfo, representation, &offset);
7576 | }
7577 | offset_r += proto_strlcpy(result+offset_r, &representation[offset], size-offset_r);
7578 | } else {
7579 | switch (hfinfo->type) {
7580 |
7581 | case FT_NONE:
7582 | case FT_PROTOCOL:
7583 | /* Prevent multiple check marks */
7584 | if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7585 | offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7586 | } else {
7587 | result[--offset_r] = '\0'; /* Remove the added trailing ',' again */
7588 | }
7589 | break;
7590 |
7591 | default:
7592 | offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7593 | break;
7594 | }
7595 | }
7596 |
7597 | if (offset_e && (offset_e < (size - 1)))
7598 | expr[offset_e++] = ',';
7599 |
7600 | 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 )))) {
7601 | const char *hf_str_val;
7602 | /* Integer types with BASE_NONE never get the numeric value. */
7603 | if (FT_IS_INT32(hfinfo->type)((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16 || (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32 )) {
7604 | hf_str_val = hf_try_val_to_str_const(fvalue_get_sinteger(finfo->value), hfinfo, "Unknown");
7605 | } 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 )) {
7606 | hf_str_val = hf_try_val_to_str_const(fvalue_get_uinteger(finfo->value), hfinfo, "Unknown");
7607 | } else if (FT_IS_INT64(hfinfo->type)((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48 || (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64 )) {
7608 | hf_str_val = hf_try_val64_to_str_const(fvalue_get_sinteger64(finfo->value), hfinfo, "Unknown");
7609 | } else { // if (FT_IS_UINT64(hfinfo->type)) {
7610 | hf_str_val = hf_try_val64_to_str_const(fvalue_get_uinteger64(finfo->value), hfinfo, "Unknown");
7611 | }
7612 | snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
7613 | offset_e = (int)strlen(expr);
7614 | } else if (hfinfo->type == FT_NONE || hfinfo->type == FT_PROTOCOL) {
7615 | /* Prevent multiple check marks */
7616 | if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7617 | offset_e += proto_item_fill_display_label(finfo, expr+offset_e, size-offset_e);
7618 | } else {
7619 | expr[--offset_e] = '\0'; /* Remove the added trailing ',' again */
7620 | }
7621 | } else {
7622 | str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_RAW, finfo->hfinfo->display);
7623 | // col_{add,append,set}_* calls ws_label_strcpy
7624 | offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7625 | wmem_free(NULL((void*)0), str);
7626 | }
7627 | i++;
7628 | }
7629 |
7630 | /* XXX: Why is only the first abbreviation returned for a multifield
7631 | * custom column? */
7632 | if (!abbrev) {
7633 | /* Store abbrev for return value */
7634 | abbrev = hfinfo->abbrev;
7635 | }
7636 |
7637 | if (occurrence == 0) {
7638 | /* Fetch next hfinfo with same name (abbrev) */
7639 | hfinfo = hfinfo_same_name_get_prev(hfinfo);
7640 | } else {
7641 | hfinfo = NULL((void*)0);
7642 | }
7643 | }
7644 | }
7645 |
7646 | if (offset_r >= (size - 1)) {
7647 | mark_truncated(result, 0, size, NULL((void*)0));
7648 | }
7649 | if (offset_e >= (size - 1)) {
7650 | mark_truncated(expr, 0, size, NULL((void*)0));
7651 | }
7652 | return abbrev ? abbrev : "";
7653 | }
7654 |
7655 | char *
7656 | proto_custom_get_filter(epan_dissect_t* edt, GSList *field_ids, int occurrence)
7657 | {
7658 | int len, prev_len, last, i;
7659 | GPtrArray *finfos;
7660 | field_info *finfo = NULL((void*)0);
7661 | header_field_info* hfinfo;
7662 |
7663 | char *filter = NULL((void*)0);
7664 | GPtrArray *filter_array;
7665 |
7666 | col_custom_t *col_custom;
7667 | int field_id;
7668 |
7669 | ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7669, __func__, "assertion failed: %s" , "field_ids != ((void*)0)"); } while (0);
7670 | filter_array = g_ptr_array_new_full(g_slist_length(field_ids), g_free);
7671 | for (GSList *iter = field_ids; iter; iter = iter->next) {
7672 | col_custom = (col_custom_t*)iter->data;
7673 | field_id = col_custom->field_id;
7674 | if (field_id == 0) {
7675 | GPtrArray *fvals = NULL((void*)0);
7676 | bool_Bool passed = dfilter_apply_full(col_custom->dfilter, edt->tree, &fvals);
7677 | if (fvals != NULL((void*)0)) {
7678 | // XXX - Handling occurrences is unusual when more
7679 | // than one field is involved, e.g. there's four
7680 | // results for tcp.port + tcp.port. We really
7681 | // want to apply it to the operands, not the output.
7682 | /* Calculate single index or set outer boundaries */
7683 | len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7684 | if (occurrence < 0) {
7685 | i = occurrence + len;
7686 | last = i;
7687 | } else if (occurrence > 0) {
7688 | i = occurrence - 1;
7689 | last = i;
7690 | } else {
7691 | i = 0;
7692 | last = len - 1;
7693 | }
7694 | if (i < 0 || i >= len) {
7695 | g_ptr_array_unref(fvals);
7696 | continue;
7697 | }
7698 | for (; i <= last; i++) {
7699 | /* XXX - Should multiple values for one
7700 | * field use set membership to reduce
7701 | * verbosity, here and below? */
7702 | char *str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DFILTER, BASE_NONE);
7703 | filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", col_custom->dftext, str);
7704 | wmem_free(NULL((void*)0), str);
7705 | if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7706 | g_ptr_array_add(filter_array, filter);
7707 | }
7708 | }
7709 | g_ptr_array_unref(fvals);
7710 | } else if (passed) {
7711 | filter = wmem_strdup(NULL((void*)0), col_custom->dftext);
7712 | if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7713 | g_ptr_array_add(filter_array, filter);
7714 | }
7715 | } else {
7716 | filter = wmem_strdup_printf(NULL((void*)0), "!(%s)", col_custom->dftext);
7717 | if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7718 | g_ptr_array_add(filter_array, filter);
7719 | }
7720 | }
7721 | continue;
7722 | }
7723 |
7724 | 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", 7724 , __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", 7724, "(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", 7724, "gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];;
7725 |
7726 | /* do we need to rewind ? */
7727 | if (!hfinfo)
7728 | return NULL((void*)0);
7729 |
7730 | if (occurrence < 0) {
7731 | /* Search other direction */
7732 | while (hfinfo->same_name_prev_id != -1) {
7733 | 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", 7733 , __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", 7733, "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", 7733, "gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo-> same_name_prev_id];;
7734 | }
7735 | }
7736 |
7737 | prev_len = 0; /* Reset handled occurrences */
7738 |
7739 | while (hfinfo) {
7740 | finfos = proto_get_finfo_ptr_array(edt->tree, hfinfo->id);
7741 |
7742 | if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7743 | if (occurrence < 0) {
7744 | hfinfo = hfinfo->same_name_next;
7745 | } else {
7746 | hfinfo = hfinfo_same_name_get_prev(hfinfo);
7747 | }
7748 | continue;
7749 | }
7750 |
7751 | /* Are there enough occurrences of the field? */
7752 | if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7753 | if (occurrence < 0) {
7754 | hfinfo = hfinfo->same_name_next;
7755 | } else {
7756 | hfinfo = hfinfo_same_name_get_prev(hfinfo);
7757 | }
7758 | prev_len += len;
7759 | continue;
7760 | }
7761 |
7762 | /* Calculate single index or set outer boundaries */
7763 | if (occurrence < 0) {
7764 | i = occurrence + len + prev_len;
7765 | last = i;
7766 | } else if (occurrence > 0) {
7767 | i = occurrence - 1 - prev_len;
7768 | last = i;
7769 | } else {
7770 | i = 0;
7771 | last = len - 1;
7772 | }
7773 |
7774 | prev_len += len; /* Count handled occurrences */
7775 |
7776 | while (i <= last) {
7777 | finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7778 |
7779 | filter = proto_construct_match_selected_string(finfo, edt);
7780 | if (filter) {
7781 | /* Only add the same expression once (especially for FT_PROTOCOL).
7782 | * The ptr array doesn't have NULL entries so g_str_equal is fine.
7783 | */
7784 | if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7785 | g_ptr_array_add(filter_array, filter);
7786 | }
7787 | }
7788 | i++;
7789 | }
7790 |
7791 | if (occurrence == 0) {
7792 | /* Fetch next hfinfo with same name (abbrev) */
7793 | hfinfo = hfinfo_same_name_get_prev(hfinfo);
7794 | } else {
7795 | hfinfo = NULL((void*)0);
7796 | }
7797 | }
7798 | }
7799 |
7800 | g_ptr_array_add(filter_array, NULL((void*)0));
7801 |
7802 | /* XXX: Should this be || or && ? */
7803 | char *output = g_strjoinv(" || ", (char **)filter_array->pdata);
7804 |
7805 | g_ptr_array_free(filter_array, true1);
7806 |
7807 | return output;
7808 | }
7809 |
7810 | /* Set text of proto_item after having already been created. */
7811 | void
7812 | proto_item_set_text(proto_item *pi, const char *format, ...)
7813 | {
7814 | field_info *fi = NULL((void*)0);
7815 | va_list ap;
7816 |
7817 | TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data )->visible) && proto_item_is_hidden((pi))) { return ; };
7818 |
7819 | fi = PITEM_FINFO(pi)((pi)->finfo);
7820 | if (fi == NULL((void*)0))
7821 | return;
7822 |
7823 | if (fi->rep) {
7824 | ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep)wmem_free(((pi)->tree_data->pinfo->pool), fi->rep );;
7825 | fi->rep = NULL((void*)0);
7826 | }
7827 |
7828 | va_start(ap, format)__builtin_va_start(ap, format);
7829 | proto_tree_set_representation(pi, format, ap);
7830 | va_end(ap)__builtin_va_end(ap);
7831 | }
7832 |
7833 | /* Append to text of proto_item after having already been created. */
7834 | void
7835 | proto_item_append_text(proto_item *pi, const char *format, ...)
7836 | {
7837 | field_info *fi = NULL((void*)0);
7838 | size_t curlen;
7839 | char *str;
7840 | va_list ap;
7841 |
7842 | TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data )->visible) && proto_item_is_hidden((pi))) { return ; };
7843 |
7844 | fi = PITEM_FINFO(pi)((pi)->finfo);
7845 | if (fi == NULL((void*)0)) {
7846 | return;
7847 | }
7848 |
7849 | if (!proto_item_is_hidden(pi)) {
7850 | /*
7851 | * If we don't already have a representation,
7852 | * generate the default representation.
7853 | */
7854 | if (fi->rep == NULL((void*)0)) {
7855 | 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;;
7856 | proto_item_fill_label(fi, fi->rep->representation, &fi->rep->value_pos);
7857 | /* Check for special case append value to FT_NONE or FT_PROTOCOL */
7858 | if ((fi->hfinfo->type == FT_NONE || fi->hfinfo->type == FT_PROTOCOL) &&
7859 | (strncmp(format, ": ", 2) == 0)) {
7860 | fi->rep->value_pos += 2;
7861 | }
7862 | }
7863 | if (fi->rep) {
7864 | curlen = strlen(fi->rep->representation);
7865 | /* curlen doesn't include the \0 byte.
7866 | * XXX: If curlen + 4 > ITEM_LABEL_LENGTH, we can't tell if
7867 | * the representation has already been truncated (of an up
7868 | * to 4 byte UTF-8 character) or is just at the maximum length
7869 | * unless we search for " [truncated]" (which may not be
7870 | * at the start.)
7871 | * It's safer to do nothing.
7872 | */
7873 | if (ITEM_LABEL_LENGTH240 > (curlen + 4)) {
7874 | va_start(ap, format)__builtin_va_start(ap, format);
7875 | str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7876 | va_end(ap)__builtin_va_end(ap);
7877 | 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" , 7877, __func__, str, -1, __uni_endptr); } } while (0); } } while (0);
7878 | /* Keep fi->rep->value_pos */
7879 | curlen = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, curlen, (const uint8_t*)str, 0);
7880 | if (curlen >= ITEM_LABEL_LENGTH240) {
7881 | /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7882 | size_t name_pos = label_find_name_pos(fi->rep);
7883 | label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7884 | }
7885 | fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7886 | }
7887 | }
7888 | }
7889 | }
7890 |
7891 | /* Prepend to text of proto_item after having already been created. */
7892 | void
7893 | proto_item_prepend_text(proto_item *pi, const char *format, ...)
7894 | {
7895 | field_info *fi = NULL((void*)0);
7896 | size_t pos;
7897 | char representation[ITEM_LABEL_LENGTH240];
7898 | char *str;
7899 | va_list ap;
7900 |
7901 | TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data )->visible) && proto_item_is_hidden((pi))) { return ; };
7902 |
7903 | fi = PITEM_FINFO(pi)((pi)->finfo);
7904 | if (fi == NULL((void*)0)) {
7905 | return;
7906 | }
7907 |
7908 | if (!proto_item_is_hidden(pi)) {
7909 | /*
7910 | * If we don't already have a representation,
7911 | * generate the default representation.
7912 | */
7913 | if (fi->rep == NULL((void*)0)) {
7914 | 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;;
7915 | proto_item_fill_label(fi, representation, &fi->rep->value_pos);
7916 | } else
7917 | (void) g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH240);
7918 |
7919 | va_start(ap, format)__builtin_va_start(ap, format);
7920 | str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7921 | va_end(ap)__builtin_va_end(ap);
7922 | 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" , 7922, __func__, str, -1, __uni_endptr); } } while (0); } } while (0);
7923 | fi->rep->value_pos += strlen(str);
7924 | pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, (const uint8_t*)str, 0);
7925 | pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, pos, (const uint8_t*)representation, 0);
7926 | /* XXX: As above, if the old representation is close to the label
7927 | * length, it might already be marked as truncated. */
7928 | if (pos >= ITEM_LABEL_LENGTH240 && (strlen(representation) + 4) <= ITEM_LABEL_LENGTH240) {
7929 | /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7930 | size_t name_pos = label_find_name_pos(fi->rep);
7931 | label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7932 | }
7933 | fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7934 | }
7935 | }
7936 |
7937 | static void
7938 | finfo_set_len(field_info *fi, const int length)
7939 | {
7940 | int length_remaining;
7941 |
7942 | 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", 7942, "length >= 0", fi->hfinfo->abbrev))));
7943 | length_remaining = tvb_captured_length_remaining(fi->ds_tvb, fi->start);
7944 | if (length > length_remaining)
7945 | fi->length = length_remaining;
7946 | else
7947 | fi->length = length;
7948 |
7949 | /* If we have an FT_PROTOCOL we need to set the length of the fvalue tvbuff as well. */
7950 | if (fvalue_type_ftenum(fi->value) == FT_PROTOCOL) {
7951 | fvalue_set_protocol_length(fi->value, fi->length);
7952 | }
7953 |
7954 | /*
7955 | * You cannot just make the "len" field of a GByteArray
7956 | * larger, if there's no data to back that length;
7957 | * you can only make it smaller.
7958 | */
7959 | if (fvalue_type_ftenum(fi->value) == FT_BYTES && fi->length > 0) {
7960 | GBytes *bytes = fvalue_get_bytes(fi->value);
7961 | size_t size;
7962 | const void *data = g_bytes_get_data(bytes, &size);
7963 | if ((size_t)fi->length <= size) {
7964 | fvalue_set_bytes_data(fi->value, data, fi->length);
7965 | }
7966 | g_bytes_unref(bytes);
7967 | }
7968 | }
7969 |
7970 | void
7971 | proto_item_set_len(proto_item *pi, const int length)
7972 | {
7973 | field_info *fi;
7974 |
7975 | if (pi == NULL((void*)0))
7976 | return;
7977 |
7978 | fi = PITEM_FINFO(pi)((pi)->finfo);
7979 | if (fi == NULL((void*)0))
7980 | return;
7981 |
7982 | finfo_set_len(fi, length);
7983 | }
7984 |
7985 | /*
7986 | * Sets the length of the item based on its start and on the specified
7987 | * offset, which is the offset past the end of the item; as the start
7988 | * in the item is relative to the beginning of the data source tvbuff,
7989 | * we need to pass in a tvbuff - the end offset is relative to the beginning
7990 | * of that tvbuff.
7991 | */
7992 | void
7993 | proto_item_set_end(proto_item *pi, tvbuff_t *tvb, unsigned end)
7994 | {
7995 | field_info *fi;
7996 | int length;
7997 |
7998 | if (pi == NULL((void*)0))
7999 | return;
8000 |
8001 | fi = PITEM_FINFO(pi)((pi)->finfo);
8002 | if (fi == NULL((void*)0))
8003 | return;
8004 |
8005 | end += tvb_raw_offset(tvb);
8006 | DISSECTOR_ASSERT(end >= fi->start)((void) ((end >= fi->start) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8006, "end >= fi->start" ))));
8007 | length = end - fi->start;
8008 |
8009 | finfo_set_len(fi, length);
8010 | }
8011 |
8012 | int
8013 | proto_item_get_len(const proto_item *pi)
8014 | {
8015 | field_info *fi;
8016 |
8017 | if (!pi)
8018 | return -1;
8019 | fi = PITEM_FINFO(pi)((pi)->finfo);
8020 | if (fi) {
8021 | return fi->length;
8022 | }
8023 | return -1;
8024 | }
8025 |
8026 | void
8027 | proto_item_set_bits_offset_len(proto_item *ti, int bits_offset, int bits_len) {
8028 | if (!ti) {
8029 | return;
8030 | }
8031 | 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);
8032 | 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);
8033 | }
8034 |
8035 | char *
8036 | proto_item_get_display_repr(wmem_allocator_t *scope, proto_item *pi)
8037 | {
8038 | field_info *fi;
8039 |
8040 | if (!pi)
8041 | return wmem_strdup(scope, "");
8042 | fi = PITEM_FINFO(pi)((pi)->finfo);
8043 | if (!fi)
8044 | return wmem_strdup(scope, "");
8045 | DISSECTOR_ASSERT(fi->hfinfo != NULL)((void) ((fi->hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8045, "fi->hfinfo != ((void*)0)" ))));
8046 | return fvalue_to_string_repr(scope, fi->value, FTREPR_DISPLAY, fi->hfinfo->display);
8047 | }
8048 |
8049 | proto_tree *
8050 | proto_tree_create_root(packet_info *pinfo)
8051 | {
8052 | proto_node *pnode;
8053 |
8054 | /* Initialize the proto_node */
8055 | pnode = g_slice_new(proto_tree)((proto_tree*) g_slice_alloc (sizeof (proto_tree)));
8056 | PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = (( void*)0); pnode->next = ((void*)0);;
8057 | pnode->parent = NULL((void*)0);
8058 | PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0);
8059 | pnode->tree_data = g_slice_new(tree_data_t)((tree_data_t*) g_slice_alloc (sizeof (tree_data_t)));
8060 |
8061 | /* Make sure we can access pinfo everywhere */
8062 | pnode->tree_data->pinfo = pinfo;
8063 |
8064 | /* Don't initialize the tree_data_t. Wait until we know we need it */
8065 | pnode->tree_data->interesting_hfids = NULL((void*)0);
8066 |
8067 | /* Set the default to false so it's easier to
8068 | * find errors; if we expect to see the protocol tree
8069 | * but for some reason the default 'visible' is not
8070 | * changed, then we'll find out very quickly. */
8071 | pnode->tree_data->visible = false0;
8072 |
8073 | /* Make sure that we fake protocols (if possible) */
8074 | pnode->tree_data->fake_protocols = true1;
8075 |
8076 | /* Keep track of the number of children */
8077 | pnode->tree_data->count = 0;
8078 |
8079 | /* Initialize our loop checks */
8080 | pnode->tree_data->idle_count_ds_tvb = NULL((void*)0);
8081 | pnode->tree_data->max_start = 0;
8082 | pnode->tree_data->start_idle_count = 0;
8083 |
8084 | return (proto_tree *)pnode;
8085 | }
8086 |
8087 |
8088 | /* "prime" a proto_tree with a single hfid that a dfilter
8089 | * is interested in. */
8090 | void
8091 | proto_tree_prime_with_hfid(proto_tree *tree _U___attribute__((unused)), const int hfid)
8092 | {
8093 | header_field_info *hfinfo;
8094 |
8095 | 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", 8095, __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", 8095, "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", 8095, "gpa_hfinfo.hfi[hfid] != ((void*)0)", "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];;
8096 | /* this field is referenced by a filter so increase the refcount.
8097 | also increase the refcount for the parent, i.e the protocol.
8098 | Don't increase the refcount if we're already printing the
8099 | type, as that is a superset of direct reference.
8100 | */
8101 | if (hfinfo->ref_type != HF_REF_TYPE_PRINT) {
8102 | hfinfo->ref_type = HF_REF_TYPE_DIRECT;
8103 | }
8104 | /* only increase the refcount if there is a parent.
8105 | if this is a protocol and not a field then parent will be -1
8106 | and there is no parent to add any refcounting for.
8107 | */
8108 | if (hfinfo->parent != -1) {
8109 | header_field_info *parent_hfinfo;
8110 | 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", 8110 , __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", 8110, "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", 8110, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!" )))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];;
8111 |
8112 | /* Mark parent as indirectly referenced unless it is already directly
8113 | * referenced, i.e. the user has specified the parent in a filter.
8114 | */
8115 | if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8116 | parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8117 | }
8118 | }
8119 |
8120 | /* "prime" a proto_tree with a single hfid that a dfilter
8121 | * is interested in. */
8122 | void
8123 | proto_tree_prime_with_hfid_print(proto_tree *tree _U___attribute__((unused)), const int hfid)
8124 | {
8125 | header_field_info *hfinfo;
8126 |
8127 | 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", 8127, __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", 8127, "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", 8127, "gpa_hfinfo.hfi[hfid] != ((void*)0)", "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];;
8128 | /* this field is referenced by an (output) filter so increase the refcount.
8129 | also increase the refcount for the parent, i.e the protocol.
8130 | */
8131 | hfinfo->ref_type = HF_REF_TYPE_PRINT;
8132 | /* only increase the refcount if there is a parent.
8133 | if this is a protocol and not a field then parent will be -1
8134 | and there is no parent to add any refcounting for.
8135 | */
8136 | if (hfinfo->parent != -1) {
8137 | header_field_info *parent_hfinfo;
8138 | 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", 8138 , __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", 8138, "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", 8138, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!" )))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];;
8139 |
8140 | /* Mark parent as indirectly referenced unless it is already directly
8141 | * referenced, i.e. the user has specified the parent in a filter.
8142 | */
8143 | if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8144 | parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8145 | }
8146 | }
8147 |
8148 | proto_tree *
8149 | proto_item_add_subtree(proto_item *pi, const int idx) {
8150 | field_info *fi;
8151 |
8152 | if (!pi)
8153 | return NULL((void*)0);
8154 |
8155 | 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", 8155, "idx >= 0 && idx < num_tree_types" ))));
8156 |
8157 | fi = PITEM_FINFO(pi)((pi)->finfo);
8158 | if (!fi)
8159 | return (proto_tree *)pi;
8160 |
8161 | fi->tree_type = idx;
8162 |
8163 | return (proto_tree *)pi;
8164 | }
8165 |
8166 | proto_tree *
8167 | proto_item_get_subtree(proto_item *pi) {
8168 | field_info *fi;
8169 |
8170 | if (!pi)
8171 | return NULL((void*)0);
8172 | fi = PITEM_FINFO(pi)((pi)->finfo);
8173 | if ( (fi) && (fi->tree_type == -1) )
8174 | return NULL((void*)0);
8175 | return (proto_tree *)pi;
8176 | }
8177 |
8178 | proto_item *
8179 | proto_item_get_parent(const proto_item *ti) {
8180 | if (!ti)
8181 | return NULL((void*)0);
8182 | return ti->parent;
8183 | }
8184 |
8185 | proto_item *
8186 | proto_item_get_parent_nth(proto_item *ti, int gen) {
8187 | if (!ti)
8188 | return NULL((void*)0);
8189 | while (gen--) {
8190 | ti = ti->parent;
8191 | if (!ti)
8192 | return NULL((void*)0);
8193 | }
8194 | return ti;
8195 | }
8196 |
8197 |
8198 | proto_item *
8199 | proto_tree_get_parent(proto_tree *tree) {
8200 | if (!tree)
8201 | return NULL((void*)0);
8202 | return (proto_item *)tree;
8203 | }
8204 |
8205 | proto_tree *
8206 | proto_tree_get_parent_tree(proto_tree *tree) {
8207 | if (!tree)
8208 | return NULL((void*)0);
8209 |
8210 | /* we're the root tree, there's no parent
8211 | return ourselves so the caller has at least a tree to attach to */
8212 | if (!tree->parent)
8213 | return tree;
8214 |
8215 | return (proto_tree *)tree->parent;
8216 | }
8217 |
8218 | proto_tree *
8219 | proto_tree_get_root(proto_tree *tree) {
8220 | if (!tree)
8221 | return NULL((void*)0);
8222 | while (tree->parent) {
8223 | tree = tree->parent;
8224 | }
8225 | return tree;
8226 | }
8227 |
8228 | void
8229 | proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
8230 | proto_item *item_to_move)
8231 | {
8232 | /* This function doesn't generate any values. It only reorganizes the protocol tree
8233 | * so we can bail out immediately if it isn't visible. */
8234 | if (!tree || !PTREE_DATA(tree)((tree)->tree_data)->visible)
8235 | return;
8236 |
8237 | 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", 8237, "item_to_move->parent == tree" ))));
8238 | 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", 8238, "fixed_item->parent == tree" ))));
8239 |
8240 | /*** cut item_to_move out ***/
8241 |
8242 | /* is item_to_move the first? */
8243 | if (tree->first_child == item_to_move) {
8244 | /* simply change first child to next */
8245 | tree->first_child = item_to_move->next;
8246 |
8247 | 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", 8247, "tree->last_child != item_to_move" ))));
8248 | } else {
8249 | proto_item *curr_item;
8250 | /* find previous and change it's next */
8251 | for (curr_item = tree->first_child; curr_item != NULL((void*)0); curr_item = curr_item->next) {
8252 | if (curr_item->next == item_to_move) {
8253 | break;
8254 | }
8255 | }
8256 |
8257 | DISSECTOR_ASSERT(curr_item)((void) ((curr_item) ? (void)0 : (proto_report_dissector_bug( "%s:%u: failed assertion \"%s\"", "epan/proto.c", 8257, "curr_item" ))));
8258 |
8259 | curr_item->next = item_to_move->next;
8260 |
8261 | /* fix last_child if required */
8262 | if (tree->last_child == item_to_move) {
8263 | tree->last_child = curr_item;
8264 | }
8265 | }
8266 |
8267 | /*** insert to_move after fixed ***/
8268 | item_to_move->next = fixed_item->next;
8269 | fixed_item->next = item_to_move;
8270 | if (tree->last_child == fixed_item) {
8271 | tree->last_child = item_to_move;
8272 | }
8273 | }
8274 |
8275 | void
8276 | proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, int start,
8277 | const int length)
8278 | {
8279 | field_info *fi;
8280 |
8281 | if (tree == NULL((void*)0))
8282 | return;
8283 |
8284 | fi = PTREE_FINFO(tree)((tree)->finfo);
8285 | if (fi == NULL((void*)0))
8286 | return;
8287 |
8288 | start += tvb_raw_offset(tvb);
8289 | DISSECTOR_ASSERT(start >= 0)((void) ((start >= 0) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8289, "start >= 0" ))));
8290 | DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8290, "length >= 0" ))));
8291 |
8292 | fi->appendix_start = start;
8293 | fi->appendix_length = length;
8294 | }
8295 |
8296 | static void
8297 | check_protocol_filter_name_or_fail(const char *filter_name)
8298 | {
8299 | /* Require at least two characters. */
8300 | if (filter_name[0] == '\0' || filter_name[1] == '\0') {
8301 | 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);
8302 | }
8303 |
8304 | if (proto_check_field_name(filter_name) != '\0') {
8305 | 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)
8306 | " 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)
8307 | " 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);
8308 | }
8309 |
8310 | /* Check that it doesn't match some very common numeric forms. */
8311 | if (filter_name[0] == '0' &&
8312 | (filter_name[1] == 'x' || filter_name[1] == 'X' ||
8313 | filter_name[1] == 'b' || filter_name[1] == 'B')) {
8314 | 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])
8315 | 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]);
8316 | }
8317 |
8318 | /* Names starting with a digit must not contain a minus sign (currently not checked at runtime). */
8319 |
8320 | /* Check that it contains at least one letter. */
8321 | bool_Bool have_letter = false0;
8322 | for (const char *s = filter_name; *s != '\0'; s++) {
8323 | if (g_ascii_isalpha(*s)((g_ascii_table[(guchar) (*s)] & G_ASCII_ALPHA) != 0)) {
8324 | have_letter = true1;
8325 | break;
8326 | }
8327 | }
8328 | if (!have_letter) {
8329 | 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)
8330 | filter_name)proto_report_dissector_bug("Protocol filter name \"%s\" must contain at least one letter a-z." , filter_name);
8331 | }
8332 |
8333 | /* Check for reserved keywords. */
8334 | if (g_hash_table_contains(proto_reserved_filter_names, filter_name)) {
8335 | 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)
8336 | " 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);
8337 | }
8338 | }
8339 |
8340 | int
8341 | proto_register_protocol(const char *name, const char *short_name,
8342 | const char *filter_name)
8343 | {
8344 | protocol_t *protocol;
8345 | header_field_info *hfinfo;
8346 |
8347 | check_protocol_filter_name_or_fail(filter_name);
8348 |
8349 | /*
8350 | * Add this protocol to the list of known protocols;
8351 | * the list is sorted by protocol short name.
8352 | */
8353 | protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8354 | protocol->name = name;
8355 | protocol->short_name = short_name;
8356 | protocol->filter_name = filter_name;
8357 | protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8358 | protocol->is_enabled = true1; /* protocol is enabled by default */
8359 | protocol->enabled_by_default = true1; /* see previous comment */
8360 | protocol->can_toggle = true1;
8361 | protocol->parent_proto_id = -1;
8362 | protocol->heur_list = NULL((void*)0);
8363 |
8364 | /* List will be sorted later by name, when all protocols completed registering */
8365 | protocols = g_list_prepend(protocols, protocol);
8366 | /*
8367 | * Make sure there's not already a protocol with any of those
8368 | * names. Crash if there is, as that's an error in the code
8369 | * or an inappropriate plugin.
8370 | * This situation has to be fixed to not register more than one
8371 | * protocol with the same name.
8372 | */
8373 | if (!g_hash_table_insert(proto_names, (void *)name, protocol)) {
8374 | /* ws_error will terminate the program */
8375 | 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)
8376 | " 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);
8377 | }
8378 | if (!g_hash_table_insert(proto_filter_names, (void *)filter_name, protocol)) {
8379 | 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)
8380 | " 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);
8381 | }
8382 | if (!g_hash_table_insert(proto_short_names, (void *)short_name, protocol)) {
8383 | 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)
8384 | " 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);
8385 | }
8386 |
8387 | /* Here we allocate a new header_field_info struct */
8388 | hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info )));
8389 | hfinfo->name = name;
8390 | hfinfo->abbrev = filter_name;
8391 | hfinfo->type = FT_PROTOCOL;
8392 | hfinfo->display = BASE_NONE;
8393 | hfinfo->strings = protocol;
8394 | hfinfo->bitmask = 0;
8395 | hfinfo->ref_type = HF_REF_TYPE_NONE;
8396 | hfinfo->blurb = NULL((void*)0);
8397 | hfinfo->parent = -1; /* This field differentiates protos and fields */
8398 |
8399 | protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8400 | return protocol->proto_id;
8401 | }
8402 |
8403 | int
8404 | proto_register_protocol_in_name_only(const char *name, const char *short_name, const char *filter_name, int parent_proto, enum ftenum field_type)
8405 | {
8406 | protocol_t *protocol;
8407 | header_field_info *hfinfo;
8408 |
8409 | /*
8410 | * Helper protocols don't need the strict rules as a "regular" protocol
8411 | * Just register it in a list and make a hf_ field from it
8412 | */
8413 | if ((field_type != FT_PROTOCOL) && (field_type != FT_BYTES)) {
8414 | 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);
8415 | }
8416 |
8417 | if (parent_proto <= 0) {
8418 | 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)
8419 | " 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);
8420 | }
8421 |
8422 | check_protocol_filter_name_or_fail(filter_name);
8423 |
8424 | /* Add this protocol to the list of helper protocols (just so it can be properly freed) */
8425 | protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8426 | protocol->name = name;
8427 | protocol->short_name = short_name;
8428 | protocol->filter_name = filter_name;
8429 | protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8430 |
8431 | /* Enabling and toggling is really determined by parent protocol,
8432 | but provide default values here */
8433 | protocol->is_enabled = true1;
8434 | protocol->enabled_by_default = true1;
8435 | protocol->can_toggle = true1;
8436 |
8437 | protocol->parent_proto_id = parent_proto;
8438 | protocol->heur_list = NULL((void*)0);
8439 |
8440 | /* List will be sorted later by name, when all protocols completed registering */
8441 | protocols = g_list_prepend(protocols, protocol);
8442 |
8443 | /* Here we allocate a new header_field_info struct */
8444 | hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info )));
8445 | hfinfo->name = name;
8446 | hfinfo->abbrev = filter_name;
8447 | hfinfo->type = field_type;
8448 | hfinfo->display = BASE_NONE;
8449 | if (field_type == FT_BYTES) {
8450 | hfinfo->display |= (BASE_NO_DISPLAY_VALUE0x00002000|BASE_PROTOCOL_INFO0x00004000);
8451 | }
8452 | hfinfo->strings = protocol;
8453 | hfinfo->bitmask = 0;
8454 | hfinfo->ref_type = HF_REF_TYPE_NONE;
8455 | hfinfo->blurb = NULL((void*)0);
8456 | hfinfo->parent = -1; /* This field differentiates protos and fields */
8457 |
8458 | protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8459 | return protocol->proto_id;
8460 | }
8461 |
8462 | bool_Bool
8463 | proto_deregister_protocol(const char *short_name)
8464 | {
8465 | protocol_t *protocol;
8466 | header_field_info *hfinfo;
8467 | int proto_id;
8468 | unsigned i;
8469 |
8470 | proto_id = proto_get_id_by_short_name(short_name);
8471 | protocol = find_protocol_by_id(proto_id);
8472 | if (protocol == NULL((void*)0))
8473 | return false0;
8474 |
8475 | g_hash_table_remove(proto_names, protocol->name);
8476 | g_hash_table_remove(proto_short_names, (void *)short_name);
8477 | g_hash_table_remove(proto_filter_names, (void *)protocol->filter_name);
8478 |
8479 | if (protocol->fields) {
8480 | for (i = 0; i < protocol->fields->len; i++) {
8481 | hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8482 | hfinfo_remove_from_gpa_name_map(hfinfo);
8483 | expert_deregister_expertinfo(hfinfo->abbrev);
8484 | g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
8485 | }
8486 | g_ptr_array_free(protocol->fields, true1);
8487 | protocol->fields = NULL((void*)0);
8488 | }
8489 |
8490 | g_list_free(protocol->heur_list);
8491 |
8492 | /* Remove this protocol from the list of known protocols */
8493 | protocols = g_list_remove(protocols, protocol);
8494 |
8495 | g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
8496 | wmem_map_remove(gpa_name_map, protocol->filter_name);
8497 |
8498 | g_free(last_field_name);
8499 | last_field_name = NULL((void*)0);
8500 |
8501 | return true1;
8502 | }
8503 |
8504 | void
8505 | proto_register_alias(const int proto_id, const char *alias_name)
8506 | {
8507 | protocol_t *protocol;
8508 |
8509 | protocol = find_protocol_by_id(proto_id);
8510 | if (alias_name && protocol) {
8511 | g_hash_table_insert(gpa_protocol_aliases, (void *) alias_name, (void *)protocol->filter_name);
8512 | }
8513 | }
8514 |
8515 | /*
8516 | * Routines to use to iterate over the protocols.
8517 | * The argument passed to the iterator routines is an opaque cookie to
8518 | * their callers; it's the GList pointer for the current element in
8519 | * the list.
8520 | * The ID of the protocol is returned, or -1 if there is no protocol.
8521 | */
8522 | int
8523 | proto_get_first_protocol(void **cookie)
8524 | {
8525 | protocol_t *protocol;
8526 |
8527 | if (protocols == NULL((void*)0))
8528 | return -1;
8529 | *cookie = protocols;
8530 | protocol = (protocol_t *)protocols->data;
8531 | return protocol->proto_id;
8532 | }
8533 |
8534 | int
8535 | proto_get_data_protocol(void *cookie)
8536 | {
8537 | GList *list_item = (GList *)cookie;
8538 |
8539 | protocol_t *protocol = (protocol_t *)list_item->data;
8540 | return protocol->proto_id;
8541 | }
8542 |
8543 | int
8544 | proto_get_next_protocol(void **cookie)
8545 | {
8546 | GList *list_item = (GList *)*cookie;
8547 | protocol_t *protocol;
8548 |
8549 | list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0) );
8550 | if (list_item == NULL((void*)0))
8551 | return -1;
8552 | *cookie = list_item;
8553 | protocol = (protocol_t *)list_item->data;
8554 | return protocol->proto_id;
8555 | }
8556 |
8557 | header_field_info *
8558 | proto_get_first_protocol_field(const int proto_id, void **cookie)
8559 | {
8560 | protocol_t *protocol = find_protocol_by_id(proto_id);
8561 |
8562 | if ((protocol == NULL((void*)0)) || (protocol->fields == NULL((void*)0)) || (protocol->fields->len == 0))
8563 | return NULL((void*)0);
8564 |
8565 | *cookie = GUINT_TO_POINTER(0)((gpointer) (gulong) (0));
8566 | return (header_field_info *)g_ptr_array_index(protocol->fields, 0)((protocol->fields)->pdata)[0];
8567 | }
8568 |
8569 | header_field_info *
8570 | proto_get_next_protocol_field(const int proto_id, void **cookie)
8571 | {
8572 | protocol_t *protocol = find_protocol_by_id(proto_id);
8573 | unsigned i = GPOINTER_TO_UINT(*cookie)((guint) (gulong) (*cookie));
8574 |
8575 | i++;
8576 |
8577 | if ((protocol->fields == NULL((void*)0)) || (i >= protocol->fields->len))
8578 | return NULL((void*)0);
8579 |
8580 | *cookie = GUINT_TO_POINTER(i)((gpointer) (gulong) (i));
8581 | return (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8582 | }
8583 |
8584 | protocol_t *
8585 | find_protocol_by_id(const int proto_id)
8586 | {
8587 | header_field_info *hfinfo;
8588 |
8589 | if (proto_id <= 0)
8590 | return NULL((void*)0);
8591 |
8592 | 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", 8592, __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", 8592, "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", 8592, "gpa_hfinfo.hfi[proto_id] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];;
8593 | if (hfinfo->type != FT_PROTOCOL) {
8594 | 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", 8594, "hfinfo->display & 0x00004000" ))));
8595 | }
8596 | return (protocol_t *)hfinfo->strings;
8597 | }
8598 |
8599 | int
8600 | proto_get_id(const protocol_t *protocol)
8601 | {
8602 | return protocol->proto_id;
8603 | }
8604 |
8605 | bool_Bool
8606 | proto_name_already_registered(const char *name)
8607 | {
8608 | DISSECTOR_ASSERT_HINT(name, "No name present")((void) ((name) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 8608, "name", "No name present"))));
8609 |
8610 | if (g_hash_table_lookup(proto_names, name) != NULL((void*)0))
8611 | return true1;
8612 | return false0;
8613 | }
8614 |
8615 | int
8616 | proto_get_id_by_filter_name(const char *filter_name)
8617 | {
8618 | const protocol_t *protocol = NULL((void*)0);
8619 |
8620 | 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", 8620, "filter_name", "No filter name present"))));
8621 |
8622 | protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
8623 |
8624 | if (protocol == NULL((void*)0))
8625 | return -1;
8626 | return protocol->proto_id;
8627 | }
8628 |
8629 | int
8630 | proto_get_id_by_short_name(const char *short_name)
8631 | {
8632 | const protocol_t *protocol = NULL((void*)0);
8633 |
8634 | 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", 8634, "short_name", "No short name present"))));
8635 |
8636 | protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
8637 |
8638 | if (protocol == NULL((void*)0))
8639 | return -1;
8640 | return protocol->proto_id;
8641 | }
8642 |
8643 | const char *
8644 | proto_get_protocol_name(const int proto_id)
8645 | {
8646 | protocol_t *protocol;
8647 |
8648 | protocol = find_protocol_by_id(proto_id);
8649 |
8650 | if (protocol == NULL((void*)0))
8651 | return NULL((void*)0);
8652 | return protocol->name;
8653 | }
8654 |
8655 | const char *
8656 | proto_get_protocol_short_name(const protocol_t *protocol)
8657 | {
8658 | if (protocol == NULL((void*)0))
8659 | return "(none)";
8660 | return protocol->short_name;
8661 | }
8662 |
8663 | const char *
8664 | proto_get_protocol_long_name(const protocol_t *protocol)
8665 | {
8666 | if (protocol == NULL((void*)0))
8667 | return "(none)";
8668 | return protocol->name;
8669 | }
8670 |
8671 | const char *
8672 | proto_get_protocol_filter_name(const int proto_id)
8673 | {
8674 | protocol_t *protocol;
8675 |
8676 | protocol = find_protocol_by_id(proto_id);
8677 | if (protocol == NULL((void*)0))
8678 | return "(none)";
8679 | return protocol->filter_name;
8680 | }
8681 |
8682 | void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
8683 | {
8684 | heur_dtbl_entry_t* heuristic_dissector;
8685 |
8686 | if (protocol == NULL((void*)0))
8687 | return;
8688 |
8689 | heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
8690 | if (heuristic_dissector != NULL((void*)0))
8691 | {
8692 | protocol->heur_list = g_list_prepend (protocol->heur_list, heuristic_dissector);
8693 | }
8694 | }
8695 |
8696 | void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, void *user_data)
8697 | {
8698 | if (protocol == NULL((void*)0))
8699 | return;
8700 |
8701 | g_list_foreach(protocol->heur_list, func, user_data);
8702 | }
8703 |
8704 | void
8705 | proto_get_frame_protocols(const wmem_list_t *layers, bool_Bool *is_ip,
8706 | bool_Bool *is_tcp, bool_Bool *is_udp,
8707 | bool_Bool *is_sctp, bool_Bool *is_tls,
8708 | bool_Bool *is_rtp,
8709 | bool_Bool *is_lte_rlc)
8710 | {
8711 | wmem_list_frame_t *protos = wmem_list_head(layers);
8712 | int proto_id;
8713 | const char *proto_name;
8714 |
8715 | /* Walk the list of a available protocols in the packet and
8716 | attempt to find "major" ones. */
8717 | /* It might make more sense to assemble and return a bitfield. */
8718 | while (protos != NULL((void*)0))
8719 | {
8720 | proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8721 | proto_name = proto_get_protocol_filter_name(proto_id);
8722 |
8723 | if (is_ip && ((!strcmp(proto_name, "ip")) ||
8724 | (!strcmp(proto_name, "ipv6")))) {
8725 | *is_ip = true1;
8726 | } else if (is_tcp && !strcmp(proto_name, "tcp")) {
8727 | *is_tcp = true1;
8728 | } else if (is_udp && !strcmp(proto_name, "udp")) {
8729 | *is_udp = true1;
8730 | } else if (is_sctp && !strcmp(proto_name, "sctp")) {
8731 | *is_sctp = true1;
8732 | } else if (is_tls && !strcmp(proto_name, "tls")) {
8733 | *is_tls = true1;
8734 | } else if (is_rtp && !strcmp(proto_name, "rtp")) {
8735 | *is_rtp = true1;
8736 | } else if (is_lte_rlc && (!strcmp(proto_name, "rlc-lte") || !strcmp(proto_name, "rlc-nr"))) {
8737 | *is_lte_rlc = true1;
8738 | }
8739 |
8740 | protos = wmem_list_frame_next(protos);
8741 | }
8742 | }
8743 |
8744 | bool_Bool
8745 | proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
8746 | {
8747 | wmem_list_frame_t *protos = wmem_list_head(layers);
8748 | int proto_id;
8749 | const char *name;
8750 |
8751 | /* Walk the list of a available protocols in the packet and
8752 | attempt to find the specified protocol. */
8753 | while (protos != NULL((void*)0))
8754 | {
8755 | proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8756 | name = proto_get_protocol_filter_name(proto_id);
8757 |
8758 | if (!strcmp(name, proto_name))
8759 | {
8760 | return true1;
8761 | }
8762 |
8763 | protos = wmem_list_frame_next(protos);
8764 | }
8765 |
8766 | return false0;
8767 | }
8768 |
8769 | char *
8770 | proto_list_layers(const packet_info *pinfo)
8771 | {
8772 | wmem_strbuf_t *buf;
8773 | wmem_list_frame_t *layers = wmem_list_head(pinfo->layers);
8774 |
8775 | buf = wmem_strbuf_new_sized(pinfo->pool, 128);
8776 |
8777 | /* Walk the list of layers in the packet and
8778 | return a string of all entries. */
8779 | while (layers != NULL((void*)0))
8780 | {
8781 | wmem_strbuf_append(buf, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(layers))((guint) (gulong) (wmem_list_frame_data(layers)))));
8782 |
8783 | layers = wmem_list_frame_next(layers);
8784 | if (layers != NULL((void*)0)) {
8785 | wmem_strbuf_append_c(buf, ':');
8786 | }
8787 | }
8788 |
8789 | return wmem_strbuf_finalize(buf);
8790 | }
8791 |
8792 | uint8_t
8793 | proto_get_layer_num(const packet_info *pinfo, const int proto_id)
8794 | {
8795 | int *proto_layer_num_ptr;
8796 |
8797 | proto_layer_num_ptr = wmem_map_lookup(pinfo->proto_layers, GINT_TO_POINTER(proto_id)((gpointer) (glong) (proto_id)));
8798 | if (proto_layer_num_ptr == NULL((void*)0)) {
8799 | return 0;
8800 | }
8801 |
8802 | return (uint8_t)*proto_layer_num_ptr;
8803 | }
8804 |
8805 | bool_Bool
8806 | proto_is_pino(const protocol_t *protocol)
8807 | {
8808 | return (protocol->parent_proto_id != -1);
8809 | }
8810 |
8811 | bool_Bool
8812 | // NOLINTNEXTLINE(misc-no-recursion)
8813 | proto_is_protocol_enabled(const protocol_t *protocol)
8814 | {
8815 | if (protocol == NULL((void*)0))
8816 | return false0;
8817 |
8818 | //parent protocol determines enable/disable for helper dissectors
8819 | if (proto_is_pino(protocol))
8820 | return proto_is_protocol_enabled(find_protocol_by_id(protocol->parent_proto_id));
8821 |
8822 | return protocol->is_enabled;
8823 | }
8824 |
8825 | bool_Bool
8826 | // NOLINTNEXTLINE(misc-no-recursion)
8827 | proto_is_protocol_enabled_by_default(const protocol_t *protocol)
8828 | {
8829 | //parent protocol determines enable/disable for helper dissectors
8830 | if (proto_is_pino(protocol))
8831 | return proto_is_protocol_enabled_by_default(find_protocol_by_id(protocol->parent_proto_id));
8832 |
8833 | return protocol->enabled_by_default;
8834 | }
8835 |
8836 | bool_Bool
8837 | // NOLINTNEXTLINE(misc-no-recursion)
8838 | proto_can_toggle_protocol(const int proto_id)
8839 | {
8840 | protocol_t *protocol;
8841 |
8842 | protocol = find_protocol_by_id(proto_id);
8843 | //parent protocol determines toggling for helper dissectors
8844 | if (proto_is_pino(protocol))
8845 | return proto_can_toggle_protocol(protocol->parent_proto_id);
8846 |
8847 | return protocol->can_toggle;
8848 | }
8849 |
8850 | void
8851 | proto_disable_by_default(const int proto_id)
8852 | {
8853 | protocol_t *protocol;
8854 |
8855 | protocol = find_protocol_by_id(proto_id);
8856 | DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8856, "protocol->can_toggle" ))));
8857 | 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", 8857, "proto_is_pino(protocol) == 0" ))));
8858 | protocol->is_enabled = false0;
8859 | protocol->enabled_by_default = false0;
8860 | }
8861 |
8862 | void
8863 | proto_set_decoding(const int proto_id, const bool_Bool enabled)
8864 | {
8865 | protocol_t *protocol;
8866 |
8867 | protocol = find_protocol_by_id(proto_id);
8868 | DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8868, "protocol->can_toggle" ))));
8869 | 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", 8869, "proto_is_pino(protocol) == 0" ))));
8870 | protocol->is_enabled = enabled;
8871 | }
8872 |
8873 | void
8874 | proto_disable_all(void)
8875 | {
8876 | /* This doesn't explicitly disable heuristic protocols,
8877 | * but the heuristic doesn't get called if the parent
8878 | * protocol isn't enabled.
8879 | */
8880 | protocol_t *protocol;
8881 | GList *list_item = protocols;
8882 |
8883 | if (protocols == NULL((void*)0))
8884 | return;
8885 |
8886 | while (list_item) {
8887 | protocol = (protocol_t *)list_item->data;
8888 | if (protocol->can_toggle) {
8889 | protocol->is_enabled = false0;
8890 | }
8891 | list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0) );
8892 | }
8893 | }
8894 |
8895 | static void
8896 | heur_reenable_cb(void *data, void *user_data _U___attribute__((unused)))
8897 | {
8898 | heur_dtbl_entry_t *heur = (heur_dtbl_entry_t*)data;
8899 |
8900 | heur->enabled = heur->enabled_by_default;
8901 | }
8902 |
8903 | void
8904 | proto_reenable_all(void)
8905 | {
8906 | protocol_t *protocol;
8907 | GList *list_item = protocols;
8908 |
8909 | if (protocols == NULL((void*)0))
8910 | return;
8911 |
8912 | while (list_item) {
8913 | protocol = (protocol_t *)list_item->data;
8914 | if (protocol->can_toggle)
8915 | protocol->is_enabled = protocol->enabled_by_default;
8916 | proto_heuristic_dissector_foreach(protocol, heur_reenable_cb, NULL((void*)0));
8917 | list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0) );
8918 | }
8919 | }
8920 |
8921 | void
8922 | proto_set_cant_toggle(const int proto_id)
8923 | {
8924 | protocol_t *protocol;
8925 |
8926 | protocol = find_protocol_by_id(proto_id);
8927 | protocol->can_toggle = false0;
8928 | }
8929 |
8930 | static int
8931 | proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
8932 | {
8933 | g_ptr_array_add(proto->fields, hfi);
8934 |
8935 | return proto_register_field_init(hfi, parent);
8936 | }
8937 |
8938 | /* for use with static arrays only, since we don't allocate our own copies
8939 | of the header_field_info struct contained within the hf_register_info struct */
8940 | void
8941 | proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
8942 | {
8943 | hf_register_info *ptr = hf;
8944 | protocol_t *proto;
8945 | int i;
8946 |
8947 | proto = find_protocol_by_id(parent);
8948 |
8949 | /* if (proto == NULL) - error or return? */
8950 |
8951 | if (proto->fields == NULL((void*)0)) {
8952 | /* Ironically, the NEW_PROTO_TREE_API was removed shortly before
8953 | * GLib introduced g_ptr_array_new_from_array, which might have
8954 | * given a reason to actually use it. (#17774)
8955 | */
8956 | proto->fields = g_ptr_array_sized_new(num_records);
8957 | }
8958 |
8959 | for (i = 0; i < num_records; i++, ptr++) {
8960 | /*
8961 | * Make sure we haven't registered this yet.
8962 | * Most fields have variables associated with them that
8963 | * are initialized to 0; some are initialized to -1 (which
8964 | * was the standard before 4.4).
8965 | *
8966 | * XXX - Since this is called almost 300000 times at startup,
8967 | * it might be nice to compare to only 0 and require
8968 | * dissectors to pass in zero for unregistered fields.
8969 | */
8970 | if (*ptr->p_id != -1 && *ptr->p_id != 0) {
8971 | REPORT_DISSECTOR_BUG(proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered" , ptr->hfinfo.abbrev)
8972 | "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)
8973 | ptr->hfinfo.abbrev)proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered" , ptr->hfinfo.abbrev);
8974 | return;
8975 | }
8976 |
8977 | *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
8978 | }
8979 | }
8980 |
8981 | /* deregister already registered fields */
8982 | void
8983 | proto_deregister_field (const int parent, int hf_id)
8984 | {
8985 | header_field_info *hfi;
8986 | protocol_t *proto;
8987 | unsigned i;
8988 |
8989 | g_free(last_field_name);
8990 | last_field_name = NULL((void*)0);
8991 |
8992 | if (hf_id == -1 || hf_id == 0)
8993 | return;
8994 |
8995 | proto = find_protocol_by_id (parent);
8996 | if (!proto || proto->fields == NULL((void*)0)) {
8997 | return;
8998 | }
8999 |
9000 | for (i = 0; i < proto->fields->len; i++) {
9001 | hfi = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9002 | if (hfi->id == hf_id) {
9003 | /* Found the hf_id in this protocol */
9004 | wmem_map_remove(gpa_name_map, hfi->abbrev);
9005 | g_ptr_array_remove_index_fast(proto->fields, i);
9006 | g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
9007 | return;
9008 | }
9009 | }
9010 | }
9011 |
9012 | /* Deregister all registered fields starting with a prefix. Use for dynamic registered fields only! */
9013 | void
9014 | proto_deregister_all_fields_with_prefix(const int parent, const char *prefix)
9015 | {
9016 | header_field_info *hfinfo;
9017 | protocol_t *proto;
9018 |
9019 | g_free(last_field_name);
9020 | last_field_name = NULL((void*)0);
9021 |
9022 | proto = find_protocol_by_id(parent);
9023 | if (proto && proto->fields && proto->fields->len > 0) {
9024 | unsigned i = proto->fields->len;
9025 | do {
9026 | i--;
9027 |
9028 | hfinfo = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9029 | 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) )) {
9030 | hfinfo_remove_from_gpa_name_map(hfinfo);
9031 | expert_deregister_expertinfo(hfinfo->abbrev);
9032 | g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
9033 | g_ptr_array_remove_index_fast(proto->fields, i);
9034 | }
9035 | } while (i > 0);
9036 | }
9037 | }
9038 |
9039 | void
9040 | proto_add_deregistered_data (void *data)
9041 | {
9042 | g_ptr_array_add(deregistered_data, data);
9043 | }
9044 |
9045 | void
9046 | proto_add_deregistered_slice (size_t block_size, void *mem_block)
9047 | {
9048 | 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 )));
9049 |
9050 | slice_data->block_size = block_size;
9051 | slice_data->mem_block = mem_block;
9052 |
9053 | g_ptr_array_add(deregistered_slice, slice_data);
9054 | }
9055 |
9056 | void proto_free_field_strings (ftenum_t field_type, unsigned int field_display, const void *field_strings)
9057 | {
9058 | if (field_strings == NULL((void*)0)) {
9059 | return;
9060 | }
9061 |
9062 | switch (field_type) {
9063 | case FT_FRAMENUM:
9064 | /* This is just an integer represented as a pointer */
9065 | break;
9066 | case FT_PROTOCOL: {
9067 | protocol_t *protocol = (protocol_t *)field_strings;
9068 | g_free((char *)protocol->short_name);
9069 | break;
9070 | }
9071 | case FT_BOOLEAN: {
9072 | true_false_string *tf = (true_false_string *)field_strings;
9073 | g_free((char *)tf->true_string);
9074 | g_free((char *)tf->false_string);
9075 | break;
9076 | }
9077 | case FT_UINT40:
9078 | case FT_INT40:
9079 | case FT_UINT48:
9080 | case FT_INT48:
9081 | case FT_UINT56:
9082 | case FT_INT56:
9083 | case FT_UINT64:
9084 | case FT_INT64: {
9085 | if (field_display & BASE_UNIT_STRING0x00001000) {
9086 | unit_name_string *unit = (unit_name_string *)field_strings;
9087 | g_free((char *)unit->singular);
9088 | g_free((char *)unit->plural);
9089 | } else if (field_display & BASE_RANGE_STRING0x00000100) {
9090 | range_string *rs = (range_string *)field_strings;
9091 | while (rs->strptr) {
9092 | g_free((char *)rs->strptr);
9093 | rs++;
9094 | }
9095 | } else if (field_display & BASE_EXT_STRING0x00000200) {
9096 | val64_string_ext *vse = (val64_string_ext *)field_strings;
9097 | val64_string *vs = (val64_string *)vse->_vs_p;
9098 | while (vs->strptr) {
9099 | g_free((char *)vs->strptr);
9100 | vs++;
9101 | }
9102 | val64_string_ext_free(vse);
9103 | field_strings = NULL((void*)0);
9104 | } else if (field_display == BASE_CUSTOM) {
9105 | /* this will be a pointer to a function, don't free that */
9106 | field_strings = NULL((void*)0);
9107 | } else {
9108 | val64_string *vs64 = (val64_string *)field_strings;
9109 | while (vs64->strptr) {
9110 | g_free((char *)vs64->strptr);
9111 | vs64++;
9112 | }
9113 | }
9114 | break;
9115 | }
9116 | case FT_CHAR:
9117 | case FT_UINT8:
9118 | case FT_INT8:
9119 | case FT_UINT16:
9120 | case FT_INT16:
9121 | case FT_UINT24:
9122 | case FT_INT24:
9123 | case FT_UINT32:
9124 | case FT_INT32:
9125 | case FT_FLOAT:
9126 | case FT_DOUBLE: {
9127 | if (field_display & BASE_UNIT_STRING0x00001000) {
9128 | unit_name_string *unit = (unit_name_string *)field_strings;
9129 | g_free((char *)unit->singular);
9130 | g_free((char *)unit->plural);
9131 | } else if (field_display & BASE_RANGE_STRING0x00000100) {
9132 | range_string *rs = (range_string *)field_strings;
9133 | while (rs->strptr) {
9134 | g_free((char *)rs->strptr);
9135 | rs++;
9136 | }
9137 | } else if (field_display & BASE_EXT_STRING0x00000200) {
9138 | value_string_ext *vse = (value_string_ext *)field_strings;
9139 | value_string *vs = (value_string *)vse->_vs_p;
9140 | while (vs->strptr) {
9141 | g_free((char *)vs->strptr);
9142 | vs++;
9143 | }
9144 | value_string_ext_free(vse);
9145 | field_strings = NULL((void*)0);
9146 | } else if (field_display == BASE_CUSTOM) {
9147 | /* this will be a pointer to a function, don't free that */
9148 | field_strings = NULL((void*)0);
9149 | } else {
9150 | value_string *vs = (value_string *)field_strings;
9151 | while (vs->strptr) {
9152 | g_free((char *)vs->strptr);
9153 | vs++;
9154 | }
9155 | }
9156 | break;
9157 | default:
9158 | break;
9159 | }
9160 | }
9161 |
9162 | if (field_type != FT_FRAMENUM) {
9163 | g_free((void *)field_strings);
9164 | }
9165 | }
9166 |
9167 | static void
9168 | free_deregistered_field (void *data, void *user_data _U___attribute__((unused)))
9169 | {
9170 | header_field_info *hfi = (header_field_info *) data;
9171 | int hf_id = hfi->id;
9172 |
9173 | g_free((char *)hfi->name);
9174 | g_free((char *)hfi->abbrev);
9175 | g_free((char *)hfi->blurb);
9176 |
9177 | proto_free_field_strings(hfi->type, hfi->display, hfi->strings);
9178 |
9179 | if (hfi->parent == -1)
9180 | 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);
9181 |
9182 | gpa_hfinfo.hfi[hf_id] = NULL((void*)0); /* Invalidate this hf_id / proto_id */
9183 | }
9184 |
9185 | static void
9186 | free_deregistered_data (void *data, void *user_data _U___attribute__((unused)))
9187 | {
9188 | g_free (data);
9189 | }
9190 |
9191 | static void
9192 | free_deregistered_slice (void *data, void *user_data _U___attribute__((unused)))
9193 | {
9194 | struct g_slice_data *slice_data = (struct g_slice_data *)data;
9195 |
9196 | g_slice_free1(slice_data->block_size, slice_data->mem_block);
9197 | 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);
9198 | }
9199 |
9200 | /* free deregistered fields and data */
9201 | void
9202 | proto_free_deregistered_fields (void)
9203 | {
9204 | expert_free_deregistered_expertinfos();
9205 |
9206 | g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL((void*)0));
9207 | g_ptr_array_free(deregistered_fields, true1);
9208 | deregistered_fields = g_ptr_array_new();
9209 |
9210 | g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL((void*)0));
9211 | g_ptr_array_free(deregistered_data, true1);
9212 | deregistered_data = g_ptr_array_new();
9213 |
9214 | g_ptr_array_foreach(deregistered_slice, free_deregistered_slice, NULL((void*)0));
9215 | g_ptr_array_free(deregistered_slice, true1);
9216 | deregistered_slice = g_ptr_array_new();
9217 | }
9218 |
9219 | static const value_string hf_display[] = {
9220 | { BASE_NONE, "BASE_NONE" },
9221 | { BASE_DEC, "BASE_DEC" },
9222 | { BASE_HEX, "BASE_HEX" },
9223 | { BASE_OCT, "BASE_OCT" },
9224 | { BASE_DEC_HEX, "BASE_DEC_HEX" },
9225 | { BASE_HEX_DEC, "BASE_HEX_DEC" },
9226 | { BASE_CUSTOM, "BASE_CUSTOM" },
9227 | { BASE_NONE|BASE_RANGE_STRING0x00000100, "BASE_NONE|BASE_RANGE_STRING" },
9228 | { BASE_DEC|BASE_RANGE_STRING0x00000100, "BASE_DEC|BASE_RANGE_STRING" },
9229 | { BASE_HEX|BASE_RANGE_STRING0x00000100, "BASE_HEX|BASE_RANGE_STRING" },
9230 | { BASE_OCT|BASE_RANGE_STRING0x00000100, "BASE_OCT|BASE_RANGE_STRING" },
9231 | { BASE_DEC_HEX|BASE_RANGE_STRING0x00000100, "BASE_DEC_HEX|BASE_RANGE_STRING" },
9232 | { BASE_HEX_DEC|BASE_RANGE_STRING0x00000100, "BASE_HEX_DEC|BASE_RANGE_STRING" },
9233 | { BASE_CUSTOM|BASE_RANGE_STRING0x00000100, "BASE_CUSTOM|BASE_RANGE_STRING" },
9234 | { BASE_NONE|BASE_VAL64_STRING0x00000400, "BASE_NONE|BASE_VAL64_STRING" },
9235 | { BASE_DEC|BASE_VAL64_STRING0x00000400, "BASE_DEC|BASE_VAL64_STRING" },
9236 | { BASE_HEX|BASE_VAL64_STRING0x00000400, "BASE_HEX|BASE_VAL64_STRING" },
9237 | { BASE_OCT|BASE_VAL64_STRING0x00000400, "BASE_OCT|BASE_VAL64_STRING" },
9238 | { BASE_DEC_HEX|BASE_VAL64_STRING0x00000400, "BASE_DEC_HEX|BASE_VAL64_STRING" },
9239 | { BASE_HEX_DEC|BASE_VAL64_STRING0x00000400, "BASE_HEX_DEC|BASE_VAL64_STRING" },
9240 | { BASE_CUSTOM|BASE_VAL64_STRING0x00000400, "BASE_CUSTOM|BASE_VAL64_STRING" },
9241 | { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
9242 | { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
9243 | { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
9244 | { BASE_PT_UDP, "BASE_PT_UDP" },
9245 | { BASE_PT_TCP, "BASE_PT_TCP" },
9246 | { BASE_PT_DCCP, "BASE_PT_DCCP" },
9247 | { BASE_PT_SCTP, "BASE_PT_SCTP" },
9248 | { BASE_OUI, "BASE_OUI" },
9249 | { 0, NULL((void*)0) } };
9250 |
9251 | const char* proto_field_display_to_string(int field_display)
9252 | {
9253 | return val_to_str_const(field_display, hf_display, "Unknown");
9254 | }
9255 |
9256 | static inline port_type
9257 | display_to_port_type(field_display_e e)
9258 | {
9259 | switch (e) {
9260 | case BASE_PT_UDP:
9261 | return PT_UDP;
9262 | case BASE_PT_TCP:
9263 | return PT_TCP;
9264 | case BASE_PT_DCCP:
9265 | return PT_DCCP;
9266 | case BASE_PT_SCTP:
9267 | return PT_SCTP;
9268 | default:
9269 | break;
9270 | }
9271 | return PT_NONE;
9272 | }
9273 |
9274 | /* temporary function containing assert part for easier profiling */
9275 | static void
9276 | tmp_fld_check_assert(header_field_info *hfinfo)
9277 | {
9278 | char* tmp_str;
9279 |
9280 | /* The field must have a name (with length > 0) */
9281 | if (!hfinfo->name || !hfinfo->name[0]) {
9282 | if (hfinfo->abbrev)
9283 | /* Try to identify the field */
9284 | 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)
9285 | hfinfo->abbrev)proto_report_dissector_bug("Field (abbrev='%s') does not have a name" , hfinfo->abbrev);
9286 | else
9287 | /* Hum, no luck */
9288 | 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)" );
9289 | }
9290 |
9291 | /* fields with an empty string for an abbreviation aren't filterable */
9292 | if (!hfinfo->abbrev || !hfinfo->abbrev[0])
9293 | 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);
9294 |
9295 | /* TODO: This check is a significant percentage of startup time (~10%),
9296 | although not nearly as slow as what's enabled by ENABLE_CHECK_FILTER.
9297 | It might be nice to have a way to disable this check when, e.g.,
9298 | running TShark many times with the same configuration. */
9299 | /* Check that the filter name (abbreviation) is legal;
9300 | * it must contain only alphanumerics, '-', "_", and ".". */
9301 | unsigned char c;
9302 | c = module_check_valid_name(hfinfo->abbrev, false0);
9303 | if (c) {
9304 | if (c == '.') {
9305 | 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);
9306 | } else if (g_ascii_isprint(c)((g_ascii_table[(guchar) (c)] & G_ASCII_PRINT) != 0)) {
9307 | 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);
9308 | } else {
9309 | 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);
9310 | }
9311 | }
9312 |
9313 | /* These types of fields are allowed to have value_strings,
9314 | * true_false_strings or a protocol_t struct
9315 | */
9316 | if (hfinfo->strings != NULL((void*)0) && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM) {
9317 | switch (hfinfo->type) {
9318 |
9319 | /*
9320 | * These types are allowed to support display value_strings,
9321 | * value64_strings, the extended versions of the previous
9322 | * two, range strings, or unit strings.
9323 | */
9324 | case FT_CHAR:
9325 | case FT_UINT8:
9326 | case FT_UINT16:
9327 | case FT_UINT24:
9328 | case FT_UINT32:
9329 | case FT_UINT40:
9330 | case FT_UINT48:
9331 | case FT_UINT56:
9332 | case FT_UINT64:
9333 | case FT_INT8:
9334 | case FT_INT16:
9335 | case FT_INT24:
9336 | case FT_INT32:
9337 | case FT_INT40:
9338 | case FT_INT48:
9339 | case FT_INT56:
9340 | case FT_INT64:
9341 | case FT_BOOLEAN:
9342 | case FT_PROTOCOL:
9343 | break;
9344 |
9345 | /*
9346 | * This is allowed to have a value of type
9347 | * enum ft_framenum_type to indicate what relationship
9348 | * the frame in question has to the frame in which
9349 | * the field is put.
9350 | */
9351 | case FT_FRAMENUM:
9352 | break;
9353 |
9354 | /*
9355 | * These types are allowed to support only unit strings.
9356 | */
9357 | case FT_FLOAT:
9358 | case FT_DOUBLE:
9359 | case FT_IEEE_11073_SFLOAT:
9360 | case FT_IEEE_11073_FLOAT:
9361 | if (!(hfinfo->display & BASE_UNIT_STRING0x00001000)) {
9362 | 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))
9363 | " (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))
9364 | 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));
9365 | }
9366 | break;
9367 |
9368 | /*
9369 | * These types are allowed to support display
9370 | * time_value_strings.
9371 | */
9372 | case FT_ABSOLUTE_TIME:
9373 | if (hfinfo->display & BASE_RANGE_STRING0x00000100 ||
9374 | hfinfo->display & BASE_EXT_STRING0x00000200 ||
9375 | hfinfo->display & BASE_VAL64_STRING0x00000400 ||
9376 | hfinfo->display & BASE_UNIT_STRING0x00001000) {
9377 | 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))
9378 | " (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))
9379 | 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));
9380 | }
9381 | break;
9382 |
9383 | /*
9384 | * This type is only allowed to support a string if it's
9385 | * a protocol (for pinos).
9386 | */
9387 | case FT_BYTES:
9388 | if (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)) {
9389 | 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))
9390 | " (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))
9391 | 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));
9392 | }
9393 | break;
9394 |
9395 | default:
9396 | 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))
9397 | " (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))
9398 | 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));
9399 | }
9400 | }
9401 |
9402 | /* TODO: This check may slow down startup, and output quite a few warnings.
9403 | It would be good to be able to enable this (and possibly other checks?)
9404 | in non-release builds. */
9405 | #ifdef ENABLE_CHECK_FILTER
9406 | /* Check for duplicate value_string values.
9407 | There are lots that have the same value *and* string, so for now only
9408 | report those that have same value but different string. */
9409 | if ((hfinfo->strings != NULL((void*)0)) &&
9410 | !(hfinfo->display & BASE_RANGE_STRING0x00000100) &&
9411 | !(hfinfo->display & BASE_UNIT_STRING0x00001000) &&
9412 | !((hfinfo->display & FIELD_DISPLAY_E_MASK0xFF) == BASE_CUSTOM) &&
9413 | (
9414 | (hfinfo->type == FT_CHAR) ||
9415 | (hfinfo->type == FT_UINT8) ||
9416 | (hfinfo->type == FT_UINT16) ||
9417 | (hfinfo->type == FT_UINT24) ||
9418 | (hfinfo->type == FT_UINT32) ||
9419 | (hfinfo->type == FT_INT8) ||
9420 | (hfinfo->type == FT_INT16) ||
9421 | (hfinfo->type == FT_INT24) ||
9422 | (hfinfo->type == FT_INT32) )) {
9423 |
9424 | if (hfinfo->display & BASE_EXT_STRING0x00000200) {
9425 | if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
9426 | const val64_string *start_values = VAL64_STRING_EXT_VS_P((const val64_string_ext*)hfinfo->strings)((const val64_string_ext*)hfinfo->strings)->_vs_p;
9427 | CHECK_HF_VALUE(val64_string, PRIu64"l" "u", start_values);
9428 | } else {
9429 | const value_string *start_values = VALUE_STRING_EXT_VS_P((const value_string_ext*)hfinfo->strings)((const value_string_ext*)hfinfo->strings)->_vs_p;
9430 | CHECK_HF_VALUE(value_string, "u", start_values);
9431 | }
9432 | } else {
9433 | const value_string *start_values = (const value_string*)hfinfo->strings;
9434 | CHECK_HF_VALUE(value_string, "u", start_values);
9435 | }
9436 | }
9437 |
9438 | if (hfinfo->type == FT_BOOLEAN) {
9439 | const true_false_string *tfs = (const true_false_string*)hfinfo->strings;
9440 | if (tfs) {
9441 | if (strcmp(tfs->false_string, tfs->true_string) == 0) {
9442 | ws_error("Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")",ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9444 , __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")" , hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs ->true_string)
9443 | hfinfo->name, hfinfo->abbrev,ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9444 , __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")" , hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs ->true_string)
9444 | tfs->false_string, tfs->true_string)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9444 , __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")" , hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs ->true_string);
9445 | }
9446 | }
9447 | }
9448 |
9449 | if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
9450 | const range_string *rs = (const range_string*)(hfinfo->strings);
9451 | if (rs) {
9452 | const range_string *this_it = rs;
9453 |
9454 | do {
9455 | if (this_it->value_max < this_it->value_min) {
9456 | 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" , 9460, __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)
9457 | hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9460, __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)
9458 | this_it->strptr,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9460, __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)
9459 | this_it->value_max, this_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9460, __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)
9460 | this_it->value_min, this_it->value_min)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9460, __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);
9461 | ++this_it;
9462 | continue;
9463 | }
9464 |
9465 | for (const range_string *prev_it=rs; prev_it < this_it; ++prev_it) {
9466 | /* Not OK if this one is completely hidden by an earlier one! */
9467 | if ((prev_it->value_min <= this_it->value_min) && (prev_it->value_max >= this_it->value_max)) {
9468 | 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" , 9474, __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)
9469 | "(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" , 9474, __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)
9470 | hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9474, __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)
9471 | prev_it->strptr, prev_it->value_min, prev_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9474, __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)
9472 | prev_it->value_max, prev_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9474, __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)
9473 | this_it->strptr, this_it->value_min, this_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9474, __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)
9474 | this_it->value_max, this_it->value_max)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9474, __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);
9475 | }
9476 | }
9477 | ++this_it;
9478 | } while (this_it->strptr);
9479 | }
9480 | }
9481 | #endif
9482 |
9483 | switch (hfinfo->type) {
9484 |
9485 | case FT_CHAR:
9486 | /* Require the char type to have BASE_HEX, BASE_OCT,
9487 | * BASE_CUSTOM, or BASE_NONE as its base.
9488 | *
9489 | * If the display value is BASE_NONE and there is a
9490 | * strings conversion then the dissector writer is
9491 | * telling us that the field's numerical value is
9492 | * meaningless; we'll avoid showing the value to the
9493 | * user.
9494 | */
9495 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9496 | case BASE_HEX:
9497 | case BASE_OCT:
9498 | case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9499 | break;
9500 | case BASE_NONE:
9501 | if (hfinfo->strings == NULL((void*)0))
9502 | 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 ))
9503 | " 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 ))
9504 | " 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 ))
9505 | 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 ))
9506 | 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 ));
9507 | break;
9508 | default:
9509 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9510 | 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)
9511 | " 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)
9512 | 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)
9513 | 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);
9514 | //wmem_free(NULL, tmp_str);
9515 | }
9516 | if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
9517 | 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 ))
9518 | 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 ))
9519 | 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 ));
9520 | }
9521 | break;
9522 | case FT_INT8:
9523 | case FT_INT16:
9524 | case FT_INT24:
9525 | case FT_INT32:
9526 | case FT_INT40:
9527 | case FT_INT48:
9528 | case FT_INT56:
9529 | case FT_INT64:
9530 | /* Hexadecimal and octal are, in printf() and everywhere
9531 | * else, unsigned so don't allow dissectors to register a
9532 | * signed field to be displayed unsigned. (Else how would
9533 | * we display negative values?)
9534 | */
9535 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9536 | case BASE_HEX:
9537 | case BASE_OCT:
9538 | case BASE_DEC_HEX:
9539 | case BASE_HEX_DEC:
9540 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9541 | 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)
9542 | 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)
9543 | 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);
9544 | //wmem_free(NULL, tmp_str);
9545 | }
9546 | /* FALL THROUGH */
9547 | case FT_UINT8:
9548 | case FT_UINT16:
9549 | case FT_UINT24:
9550 | case FT_UINT32:
9551 | case FT_UINT40:
9552 | case FT_UINT48:
9553 | case FT_UINT56:
9554 | case FT_UINT64:
9555 | 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 ))) {
9556 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9557 | if (hfinfo->type != FT_UINT16) {
9558 | 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))
9559 | 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))
9560 | 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));
9561 | }
9562 | if (hfinfo->strings != NULL((void*)0)) {
9563 | 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)
9564 | 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)
9565 | 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);
9566 | }
9567 | if (hfinfo->bitmask != 0) {
9568 | 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)
9569 | 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)
9570 | 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);
9571 | }
9572 | wmem_free(NULL((void*)0), tmp_str);
9573 | break;
9574 | }
9575 |
9576 | if (hfinfo->display == BASE_OUI) {
9577 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9578 | if (hfinfo->type != FT_UINT24) {
9579 | 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))
9580 | 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))
9581 | 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));
9582 | }
9583 | if (hfinfo->strings != NULL((void*)0)) {
9584 | 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)
9585 | 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)
9586 | 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);
9587 | }
9588 | if (hfinfo->bitmask != 0) {
9589 | 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)
9590 | 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)
9591 | 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);
9592 | }
9593 | wmem_free(NULL((void*)0), tmp_str);
9594 | break;
9595 | }
9596 |
9597 | /* Require integral types (other than frame number,
9598 | * which is always displayed in decimal) to have a
9599 | * number base.
9600 | *
9601 | * If the display value is BASE_NONE and there is a
9602 | * strings conversion then the dissector writer is
9603 | * telling us that the field's numerical value is
9604 | * meaningless; we'll avoid showing the value to the
9605 | * user.
9606 | */
9607 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9608 | case BASE_DEC:
9609 | case BASE_HEX:
9610 | case BASE_OCT:
9611 | case BASE_DEC_HEX:
9612 | case BASE_HEX_DEC:
9613 | case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9614 | break;
9615 | case BASE_NONE:
9616 | if (hfinfo->strings == NULL((void*)0)) {
9617 | 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 ))
9618 | " 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 ))
9619 | " 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 ))
9620 | 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 ))
9621 | 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 ));
9622 | }
9623 | if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
9624 | 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 ))
9625 | " 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 ))
9626 | " 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 ))
9627 | 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 ))
9628 | 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 ));
9629 | }
9630 | break;
9631 |
9632 | default:
9633 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9634 | 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)
9635 | " 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)
9636 | 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)
9637 | 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);
9638 | //wmem_free(NULL, tmp_str);
9639 | }
9640 | break;
9641 | case FT_BYTES:
9642 | case FT_UINT_BYTES:
9643 | /* Require bytes to have a "display type" that could
9644 | * add a character between displayed bytes.
9645 | */
9646 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9647 | case BASE_NONE:
9648 | case SEP_DOT:
9649 | case SEP_DASH:
9650 | case SEP_COLON:
9651 | case SEP_SPACE:
9652 | break;
9653 | default:
9654 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9655 | 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)
9656 | 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);
9657 | //wmem_free(NULL, tmp_str);
9658 | }
9659 | if (hfinfo->bitmask != 0)
9660 | 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 ))
9661 | 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 ))
9662 | 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 ));
9663 | //allowed to support string if its a protocol (for pinos)
9664 | if ((hfinfo->strings != NULL((void*)0)) && (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)))
9665 | 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 ))
9666 | 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 ))
9667 | 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 ));
9668 | break;
9669 |
9670 | case FT_PROTOCOL:
9671 | case FT_FRAMENUM:
9672 | if (hfinfo->display != BASE_NONE) {
9673 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9674 | 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)
9675 | 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)
9676 | 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);
9677 | //wmem_free(NULL, tmp_str);
9678 | }
9679 | if (hfinfo->bitmask != 0)
9680 | 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 ))
9681 | 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 ))
9682 | 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 ));
9683 | break;
9684 |
9685 | case FT_BOOLEAN:
9686 | break;
9687 |
9688 | case FT_ABSOLUTE_TIME:
9689 | if (!FIELD_DISPLAY_IS_ABSOLUTE_TIME(hfinfo->display)(((hfinfo->display) & 0xFF) >= ABSOLUTE_TIME_LOCAL && ((hfinfo->display) & 0xFF) <= ABSOLUTE_TIME_UNIX)) {
9690 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9691 | 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)
9692 | 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);
9693 | //wmem_free(NULL, tmp_str);
9694 | }
9695 | if (hfinfo->bitmask != 0)
9696 | REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a bitmask",proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask" , hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type ))
9697 | hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask" , hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type ))
9698 | ftype_name(hfinfo->type))proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask" , hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type ));
9699 | break;
9700 |
9701 | case FT_STRING:
9702 | case FT_STRINGZ:
9703 | case FT_UINT_STRING:
9704 | case FT_STRINGZPAD:
9705 | case FT_STRINGZTRUNC:
9706 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9707 | case BASE_NONE:
9708 | case BASE_STR_WSP:
9709 | break;
9710 |
9711 | default:
9712 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9713 | REPORT_DISSECTOR_BUG("Field '%s' (%s) is an 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)
9714 | " 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)
9715 | 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)
9716 | 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);
9717 | //wmem_free(NULL, tmp_str);
9718 | }
9719 |
9720 | if (hfinfo->bitmask != 0)
9721 | 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 ))
9722 | 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 ))
9723 | 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 ));
9724 | if (hfinfo->strings != NULL((void*)0))
9725 | 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 ))
9726 | 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 ))
9727 | 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 ));
9728 | break;
9729 |
9730 | case FT_IPv4:
9731 | switch (hfinfo->display) {
9732 | case BASE_NONE:
9733 | case BASE_NETMASK:
9734 | break;
9735 |
9736 | default:
9737 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9738 | 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)
9739 | " 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)
9740 | 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)
9741 | 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);
9742 | //wmem_free(NULL, tmp_str);
9743 | break;
9744 | }
9745 | break;
9746 | case FT_FLOAT:
9747 | case FT_DOUBLE:
9748 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9749 | case BASE_NONE:
9750 | case BASE_DEC:
9751 | case BASE_HEX:
9752 | case BASE_EXP:
9753 | case BASE_CUSTOM:
9754 | break;
9755 | default:
9756 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9757 | 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)
9758 | " 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)
9759 | 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)
9760 | 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);
9761 | //wmem_free(NULL, tmp_str);
9762 | }
9763 | if (hfinfo->bitmask != 0)
9764 | 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 ))
9765 | 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 ))
9766 | 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 ));
9767 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM && (hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9768 | 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 ))
9769 | 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 ))
9770 | 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 ));
9771 | break;
9772 | case FT_IEEE_11073_SFLOAT:
9773 | case FT_IEEE_11073_FLOAT:
9774 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_NONE) {
9775 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9776 | 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)
9777 | 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)
9778 | 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)
9779 | 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);
9780 | //wmem_free(NULL, tmp_str);
9781 | }
9782 | if (hfinfo->bitmask != 0)
9783 | 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 ))
9784 | 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 ))
9785 | 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 ));
9786 | if ((hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9787 | 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 ))
9788 | 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 ))
9789 | 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 ));
9790 | break;
9791 | default:
9792 | if (hfinfo->display != BASE_NONE) {
9793 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9794 | 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)
9795 | 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)
9796 | 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)
9797 | 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);
9798 | //wmem_free(NULL, tmp_str);
9799 | }
9800 | if (hfinfo->bitmask != 0)
9801 | 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 ))
9802 | 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 ))
9803 | 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 ));
9804 | if (hfinfo->strings != NULL((void*)0))
9805 | 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 ))
9806 | 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 ))
9807 | 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 ));
9808 | break;
9809 | }
9810 | }
9811 |
9812 | static void
9813 | register_type_length_mismatch(void)
9814 | {
9815 | static ei_register_info ei[] = {
9816 | { &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)}} }},
9817 | { &ei_type_length_mismatch_warn, { "_ws.type_length.mismatch_warn", PI_MALFORMED0x07000000, PI_WARN0x00600000, "Trying to fetch X with length Y", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE , BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE , -1, ((void*)0)}} }},
9818 | };
9819 |
9820 | expert_module_t* expert_type_length_mismatch;
9821 |
9822 | proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
9823 |
9824 | expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
9825 | expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9826 |
9827 | /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
9828 | disabling them makes no sense. */
9829 | proto_set_cant_toggle(proto_type_length_mismatch);
9830 | }
9831 |
9832 | static void
9833 | register_byte_array_string_decodinws_error(void)
9834 | {
9835 | static ei_register_info ei[] = {
9836 | { &ei_byte_array_string_decoding_failed_error,
9837 | { "_ws.byte_array_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9838 | "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)}}
9839 | }
9840 | },
9841 | };
9842 |
9843 | expert_module_t* expert_byte_array_string_decoding_error;
9844 |
9845 | proto_byte_array_string_decoding_error =
9846 | proto_register_protocol("Byte Array-String Decoding Error",
9847 | "Byte Array-string decoding error",
9848 | "_ws.byte_array_string.decoding_error");
9849 |
9850 | expert_byte_array_string_decoding_error =
9851 | expert_register_protocol(proto_byte_array_string_decoding_error);
9852 | expert_register_field_array(expert_byte_array_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9853 |
9854 | /* "Byte Array-String Decoding Error" isn't really a protocol, it's an error indication;
9855 | disabling them makes no sense. */
9856 | proto_set_cant_toggle(proto_byte_array_string_decoding_error);
9857 | }
9858 |
9859 | static void
9860 | register_date_time_string_decodinws_error(void)
9861 | {
9862 | static ei_register_info ei[] = {
9863 | { &ei_date_time_string_decoding_failed_error,
9864 | { "_ws.date_time_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9865 | "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)}}
9866 | }
9867 | },
9868 | };
9869 |
9870 | expert_module_t* expert_date_time_string_decoding_error;
9871 |
9872 | proto_date_time_string_decoding_error =
9873 | proto_register_protocol("Date and Time-String Decoding Error",
9874 | "Date and Time-string decoding error",
9875 | "_ws.date_time_string.decoding_error");
9876 |
9877 | expert_date_time_string_decoding_error =
9878 | expert_register_protocol(proto_date_time_string_decoding_error);
9879 | expert_register_field_array(expert_date_time_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9880 |
9881 | /* "Date and Time-String Decoding Error" isn't really a protocol, it's an error indication;
9882 | disabling them makes no sense. */
9883 | proto_set_cant_toggle(proto_date_time_string_decoding_error);
9884 | }
9885 |
9886 | static void
9887 | register_string_errors(void)
9888 | {
9889 | static ei_register_info ei[] = {
9890 | { &ei_string_trailing_characters,
9891 | { "_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)}} }
9892 | },
9893 | };
9894 |
9895 | expert_module_t* expert_string_errors;
9896 |
9897 | proto_string_errors = proto_register_protocol("String Errors", "String errors", "_ws.string");
9898 |
9899 | expert_string_errors = expert_register_protocol(proto_string_errors);
9900 | expert_register_field_array(expert_string_errors, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9901 |
9902 | /* "String Errors" isn't really a protocol, it's an error indication;
9903 | disabling them makes no sense. */
9904 | proto_set_cant_toggle(proto_string_errors);
9905 | }
9906 |
9907 | static int
9908 | proto_register_field_init(header_field_info *hfinfo, const int parent)
9909 | {
9910 |
9911 | tmp_fld_check_assert(hfinfo);
9912 |
9913 | hfinfo->parent = parent;
9914 | hfinfo->same_name_next = NULL((void*)0);
9915 | hfinfo->same_name_prev_id = -1;
9916 |
9917 | /* if we always add and never delete, then id == len - 1 is correct */
9918 | if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
9919 | if (!gpa_hfinfo.hfi) {
9920 | gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000);
9921 | gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
9922 | /* The entry with index 0 is not used. */
9923 | gpa_hfinfo.hfi[0] = NULL((void*)0);
9924 | gpa_hfinfo.len = 1;
9925 | } else {
9926 | gpa_hfinfo.allocated_len += 1000;
9927 | gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
9928 | sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
9929 | /*ws_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
9930 | }
9931 | }
9932 | gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
9933 | gpa_hfinfo.len++;
9934 | hfinfo->id = gpa_hfinfo.len - 1;
9935 |
9936 | /* if we have real names, enter this field in the name tree */
9937 | /* Already checked in tmp_fld_check_assert */
9938 | /*if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) */
9939 | {
9940 |
9941 | header_field_info *same_name_next_hfinfo;
9942 |
9943 | /* We allow multiple hfinfo's to be registered under the same
9944 | * abbreviation. This was done for X.25, as, depending
9945 | * on whether it's modulo-8 or modulo-128 operation,
9946 | * some bitfield fields may be in different bits of
9947 | * a byte, and we want to be able to refer to that field
9948 | * with one name regardless of whether the packets
9949 | * are modulo-8 or modulo-128 packets. */
9950 |
9951 | /* wmem_map_insert - if key is already present the previous
9952 | * hfinfo with the same key/name is returned, otherwise NULL */
9953 | same_name_hfinfo = wmem_map_insert(gpa_name_map, (void *) (hfinfo->abbrev), hfinfo);
9954 | if (same_name_hfinfo) {
9955 | /* There's already a field with this name.
9956 | * Put the current field *before* that field
9957 | * in the list of fields with this name, Thus,
9958 | * we end up with an effectively
9959 | * doubly-linked-list of same-named hfinfo's,
9960 | * with the head of the list (stored in the
9961 | * hash) being the last seen hfinfo.
9962 | */
9963 | same_name_next_hfinfo =
9964 | same_name_hfinfo->same_name_next;
9965 |
9966 | hfinfo->same_name_next = same_name_next_hfinfo;
9967 | if (same_name_next_hfinfo)
9968 | same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
9969 |
9970 | same_name_hfinfo->same_name_next = hfinfo;
9971 | hfinfo->same_name_prev_id = same_name_hfinfo->id;
9972 | #ifdef ENABLE_CHECK_FILTER
9973 | while (same_name_hfinfo) {
9974 | if (!ftype_similar_types(hfinfo->type, same_name_hfinfo->type))
9975 | ws_error("'%s' exists multiple times with incompatible types: %s and %s", hfinfo->abbrev, ftype_name(hfinfo->type), ftype_name(same_name_hfinfo->type))ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9975 , __func__, "'%s' exists multiple times with incompatible types: %s and %s" , hfinfo->abbrev, ftype_name(hfinfo->type), ftype_name( same_name_hfinfo->type));
9976 | same_name_hfinfo = same_name_hfinfo->same_name_next;
9977 | }
9978 | #endif
9979 | }
9980 | }
9981 |
9982 | return hfinfo->id;
9983 | }
9984 |
9985 | void
9986 | proto_register_subtree_array(int * const *indices, const int num_indices)
9987 | {
9988 | int i;
9989 | int *const *ptr = indices;
9990 |
9991 | /*
9992 | * If we've already allocated the array of tree types, expand
9993 | * it; this lets plugins such as mate add tree types after
9994 | * the initial startup. (If we haven't already allocated it,
9995 | * we don't allocate it; on the first pass, we just assign
9996 | * ett values and keep track of how many we've assigned, and
9997 | * when we're finished registering all dissectors we allocate
9998 | * the array, so that we do only one allocation rather than
9999 | * wasting CPU time and memory by growing the array for each
10000 | * dissector that registers ett values.)
10001 | */
10002 | if (tree_is_expanded != NULL((void*)0)) {
10003 | tree_is_expanded = (uint32_t *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(uint32_t));
10004 |
10005 | /* set new items to 0 */
10006 | /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of uint32_t to 0) */
10007 | for (i = num_tree_types; i < num_tree_types + num_indices; i++)
10008 | tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
10009 | }
10010 |
10011 | /*
10012 | * Assign "num_indices" subtree numbers starting at "num_tree_types",
10013 | * returning the indices through the pointers in the array whose
10014 | * first element is pointed to by "indices", and update
10015 | * "num_tree_types" appropriately.
10016 | */
10017 | for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
10018 | if (**ptr != -1 && **ptr != 0) {
10019 | 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.")
10020 | " 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.")
10021 | " 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.")
10022 | " 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.");
10023 | }
10024 | **ptr = num_tree_types;
10025 | }
10026 | }
10027 |
10028 | static void
10029 | mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos)
10030 | {
10031 | static const char trunc_str[] = " [" UTF8_HORIZONTAL_ELLIPSIS"\u2026" "] ";
10032 | const size_t trunc_len = sizeof(trunc_str)-2; /* Default do not include the trailing space. */
10033 | char *last_char;
10034 |
10035 | /* ..... field_name: dataaaaaaaaaaaaa
10036 | * |
10037 | * ^^^^^ name_pos
10038 | *
10039 | * ..... field_name […]: dataaaaaaaaaaaaa
10040 | *
10041 | * name_pos==0 means that we have only data or only a field_name
10042 | */
10043 |
10044 | ws_abort_if_fail(size > trunc_len)do { if ((1) && !(size > trunc_len)) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10044, __func__, "assertion failed: %s" , "size > trunc_len"); } while (0);
10045 |
10046 | if (name_pos >= size - trunc_len) {
10047 | /* No room for trunc_str after the field_name, put it first. */
10048 | name_pos = 0;
10049 | }
10050 |
10051 | memmove(label_str + name_pos + trunc_len, label_str + name_pos, size - name_pos - trunc_len);
10052 | if (name_pos == 0) {
10053 | /* Copy the trunc_str after the first byte, so that we don't have a leading space in the label. */
10054 | memcpy(label_str, trunc_str + 1, trunc_len);
10055 | } else {
10056 | memcpy(label_str + name_pos, trunc_str, trunc_len);
10057 | }
10058 | /* in general, label_str is UTF-8
10059 | we can truncate it only at the beginning of a new character
10060 | we go backwards from the byte right after our buffer and
10061 | find the next starting byte of a UTF-8 character, this is
10062 | where we cut
10063 | there's no need to use g_utf8_find_prev_char(), the search
10064 | will always succeed since we copied trunc_str into the
10065 | buffer */
10066 | /* g_utf8_prev_char does not deference the memory address
10067 | * passed in (until after decrementing it, so it is perfectly
10068 | * legal to pass in a pointer one past the last element.
10069 | */
10070 | last_char = g_utf8_prev_char(label_str + size);
10071 | *last_char = '\0';
10072 | /* This is unnecessary (above always terminates), but try to
10073 | * convince Coverity to avoid dozens of false positives. */
10074 | label_str[size - 1] = '\0';
10075 |
10076 | if (value_pos && *value_pos > 0) {
10077 | if (name_pos == 0) {
10078 | *value_pos += trunc_len;
10079 | } else {
10080 | /* Move one back to include trunc_str in the value. */
10081 | *value_pos -= 1;
10082 | }
10083 | }
10084 |
10085 | /* Check if value_pos is past label_str. */
10086 | if (value_pos && *value_pos >= size) {
10087 | *value_pos = size - 1;
10088 | }
10089 | }
10090 |
10091 | static void
10092 | label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos)
10093 | {
10094 | mark_truncated(label_str, name_pos, ITEM_LABEL_LENGTH240, value_pos);
10095 | }
10096 |
10097 | static size_t
10098 | label_fill(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, size_t *value_pos)
10099 | {
10100 | size_t name_pos;
10101 |
10102 | /* "%s: %s", hfinfo->name, text */
10103 | 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);
10104 | if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10105 | pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10106 | if (value_pos) {
10107 | *value_pos = pos;
10108 | }
10109 | pos = ws_label_strcpy(label_str, ITEM_LABEL_LENGTH240, pos, (const uint8_t*)(text ? text : "(null)"), label_strcat_flags(hfinfo));
10110 | }
10111 |
10112 | if (pos >= ITEM_LABEL_LENGTH240) {
10113 | /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10114 | label_mark_truncated(label_str, name_pos, value_pos);
10115 | }
10116 |
10117 | return pos;
10118 | }
10119 |
10120 | static size_t
10121 | label_fill_descr(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, const char *descr, size_t *value_pos)
10122 | {
10123 | size_t name_pos;
10124 |
10125 | /* "%s: %s (%s)", hfinfo->name, text, descr */
10126 | 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);
10127 | if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10128 | pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10129 | if (value_pos) {
10130 | *value_pos = pos;
10131 | }
10132 | if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
10133 | 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);
10134 | 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);
10135 | } else {
10136 | 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);
10137 | pos = label_concat(label_str, pos, (const uint8_t*)" (")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)" (", 0);
10138 | 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);
10139 | pos = label_concat(label_str, pos, (const uint8_t*)")")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)")", 0);
10140 | }
10141 | }
10142 |
10143 | if (pos >= ITEM_LABEL_LENGTH240) {
10144 | /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10145 | label_mark_truncated(label_str, name_pos, value_pos);
10146 | }
10147 |
10148 | return pos;
10149 | }
10150 |
10151 | void
10152 | proto_item_fill_label(const field_info *fi, char *label_str, size_t *value_pos)
10153 | {
10154 | const header_field_info *hfinfo;
10155 | const char *str;
10156 | const uint8_t *bytes;
10157 | uint32_t integer;
10158 | const ipv4_addr_and_mask *ipv4;
10159 | const ipv6_addr_and_prefix *ipv6;
10160 | const e_guid_t *guid;
10161 | char *name;
10162 | address addr;
10163 | char *addr_str;
10164 | char *tmp;
10165 |
10166 | if (!label_str) {
10167 | ws_warning("NULL label_str passed to proto_item_fill_label.")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 10167, __func__, "NULL label_str passed to proto_item_fill_label." ); } } while (0);
10168 | return;
10169 | }
10170 |
10171 | label_str[0]= '\0';
10172 |
10173 | if (!fi) {
10174 | return;
10175 | }
10176 |
10177 | hfinfo = fi->hfinfo;
10178 |
10179 | switch (hfinfo->type) {
10180 | case FT_NONE:
10181 | case FT_PROTOCOL:
10182 | (void) g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH240);
10183 | if (value_pos) {
10184 | *value_pos = strlen(hfinfo->name);
10185 | }
10186 | break;
10187 |
10188 | case FT_BOOLEAN:
10189 | fill_label_boolean(fi, label_str, value_pos);
10190 | break;
10191 |
10192 | case FT_BYTES:
10193 | case FT_UINT_BYTES:
10194 | tmp = format_bytes_hfinfo(NULL((void*)0), hfinfo,
10195 | fvalue_get_bytes_data(fi->value),
10196 | (unsigned)fvalue_length2(fi->value));
10197 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10198 | wmem_free(NULL((void*)0), tmp);
10199 | break;
10200 |
10201 | case FT_CHAR:
10202 | if (hfinfo->bitmask) {
10203 | fill_label_bitfield_char(fi, label_str, value_pos);
10204 | } else {
10205 | fill_label_char(fi, label_str, value_pos);
10206 | }
10207 | break;
10208 |
10209 | /* Four types of integers to take care of:
10210 | * Bitfield, with val_string
10211 | * Bitfield, w/o val_string
10212 | * Non-bitfield, with val_string
10213 | * Non-bitfield, w/o val_string
10214 | */
10215 | case FT_UINT8:
10216 | case FT_UINT16:
10217 | case FT_UINT24:
10218 | case FT_UINT32:
10219 | if (hfinfo->bitmask) {
10220 | fill_label_bitfield(fi, label_str, value_pos, false0);
10221 | } else {
10222 | fill_label_number(fi, label_str, value_pos, false0);
10223 | }
10224 | break;
10225 |
10226 | case FT_FRAMENUM:
10227 | fill_label_number(fi, label_str, value_pos, false0);
10228 | break;
10229 |
10230 | case FT_UINT40:
10231 | case FT_UINT48:
10232 | case FT_UINT56:
10233 | case FT_UINT64:
10234 | if (hfinfo->bitmask) {
10235 | fill_label_bitfield64(fi, label_str, value_pos, false0);
10236 | } else {
10237 | fill_label_number64(fi, label_str, value_pos, false0);
10238 | }
10239 | break;
10240 |
10241 | case FT_INT8:
10242 | case FT_INT16:
10243 | case FT_INT24:
10244 | case FT_INT32:
10245 | if (hfinfo->bitmask) {
10246 | fill_label_bitfield(fi, label_str, value_pos, true1);
10247 | } else {
10248 | fill_label_number(fi, label_str, value_pos, true1);
10249 | }
10250 | break;
10251 |
10252 | case FT_INT40:
10253 | case FT_INT48:
10254 | case FT_INT56:
10255 | case FT_INT64:
10256 | if (hfinfo->bitmask) {
10257 | fill_label_bitfield64(fi, label_str, value_pos, true1);
10258 | } else {
10259 | fill_label_number64(fi, label_str, value_pos, true1);
10260 | }
10261 | break;
10262 |
10263 | case FT_FLOAT:
10264 | case FT_DOUBLE:
10265 | fill_label_float(fi, label_str, value_pos);
10266 | break;
10267 |
10268 | case FT_ABSOLUTE_TIME:
10269 | {
10270 | const nstime_t *value = fvalue_get_time(fi->value);
10271 | int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
10272 | if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
10273 | flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
10274 | }
10275 | if (hfinfo->strings) {
10276 | /*
10277 | * Table of time valus to be displayed
10278 | * specially.
10279 | */
10280 | const char *time_string = try_time_val_to_str(value, (const time_value_string *)hfinfo->strings);
10281 | if (time_string != NULL((void*)0)) {
10282 | label_fill(label_str, 0, hfinfo, time_string, value_pos);
10283 | break;
10284 | }
10285 | }
10286 | tmp = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
10287 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10288 | wmem_free(NULL((void*)0), tmp);
10289 | break;
10290 | }
10291 | case FT_RELATIVE_TIME:
10292 | tmp = rel_time_to_str(NULL((void*)0), fvalue_get_time(fi->value));
10293 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10294 | wmem_free(NULL((void*)0), tmp);
10295 | break;
10296 |
10297 | case FT_IPXNET:
10298 | integer = fvalue_get_uinteger(fi->value);
10299 | tmp = get_ipxnet_name(NULL((void*)0), integer);
10300 | addr_str = wmem_strdup_printf(NULL((void*)0), "0x%08X", integer);
10301 | label_fill_descr(label_str, 0, hfinfo, tmp, addr_str, value_pos);
10302 | wmem_free(NULL((void*)0), tmp);
10303 | wmem_free(NULL((void*)0), addr_str);
10304 | break;
10305 |
10306 | case FT_VINES:
10307 | addr.type = AT_VINES;
10308 | addr.len = VINES_ADDR_LEN6;
10309 | addr.data = fvalue_get_bytes_data(fi->value);
10310 |
10311 | addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10312 | label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10313 | wmem_free(NULL((void*)0), addr_str);
10314 | break;
10315 |
10316 | case FT_ETHER:
10317 | bytes = fvalue_get_bytes_data(fi->value);
10318 |
10319 | addr.type = AT_ETHER;
10320 | addr.len = 6;
10321 | addr.data = bytes;
10322 |
10323 | addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10324 | label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10325 | wmem_free(NULL((void*)0), addr_str);
10326 | break;
10327 |
10328 | case FT_IPv4:
10329 | ipv4 = fvalue_get_ipv4(fi->value);
10330 | set_address_ipv4(&addr, ipv4);
10331 |
10332 | if (hfinfo->display == BASE_NETMASK) {
10333 | addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10334 | } else {
10335 | addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10336 | }
10337 | label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10338 | wmem_free(NULL((void*)0), addr_str);
10339 | free_address(&addr);
10340 | break;
10341 |
10342 | case FT_IPv6:
10343 | ipv6 = fvalue_get_ipv6(fi->value);
10344 | set_address_ipv6(&addr, ipv6);
10345 |
10346 | addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10347 | label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10348 | wmem_free(NULL((void*)0), addr_str);
10349 | free_address(&addr);
10350 | break;
10351 |
10352 | case FT_FCWWN:
10353 | bytes = fvalue_get_bytes_data(fi->value);
10354 | addr.type = AT_FCWWN;
10355 | addr.len = FCWWN_ADDR_LEN8;
10356 | addr.data = bytes;
10357 |
10358 | addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10359 | label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10360 | wmem_free(NULL((void*)0), addr_str);
10361 | break;
10362 |
10363 | case FT_GUID:
10364 | guid = fvalue_get_guid(fi->value);
10365 | tmp = guid_to_str(NULL((void*)0), guid);
10366 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10367 | wmem_free(NULL((void*)0), tmp);
10368 | break;
10369 |
10370 | case FT_OID:
10371 | bytes = fvalue_get_bytes_data(fi->value);
10372 | name = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10373 | tmp = oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10374 | if (name) {
10375 | label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10376 | wmem_free(NULL((void*)0), name);
10377 | } else {
10378 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10379 | }
10380 | wmem_free(NULL((void*)0), tmp);
10381 | break;
10382 |
10383 | case FT_REL_OID:
10384 | bytes = fvalue_get_bytes_data(fi->value);
10385 | name = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10386 | tmp = rel_oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10387 | if (name) {
10388 | label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10389 | wmem_free(NULL((void*)0), name);
10390 | } else {
10391 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10392 | }
10393 | wmem_free(NULL((void*)0), tmp);
10394 | break;
10395 |
10396 | case FT_SYSTEM_ID:
10397 | bytes = fvalue_get_bytes_data(fi->value);
10398 | tmp = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10399 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10400 | wmem_free(NULL((void*)0), tmp);
10401 | break;
10402 |
10403 | case FT_EUI64:
10404 | bytes = fvalue_get_bytes_data(fi->value);
10405 | addr.type = AT_EUI64;
10406 | addr.len = EUI64_ADDR_LEN8;
10407 | addr.data = bytes;
10408 |
10409 | addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10410 | label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10411 | wmem_free(NULL((void*)0), addr_str);
10412 | break;
10413 | case FT_STRING:
10414 | case FT_STRINGZ:
10415 | case FT_UINT_STRING:
10416 | case FT_STRINGZPAD:
10417 | case FT_STRINGZTRUNC:
10418 | case FT_AX25:
10419 | str = fvalue_get_string(fi->value);
10420 | label_fill(label_str, 0, hfinfo, str, value_pos);
10421 | break;
10422 |
10423 | case FT_IEEE_11073_SFLOAT:
10424 | case FT_IEEE_11073_FLOAT:
10425 | fill_label_ieee_11073_float(fi, label_str, value_pos);
10426 | break;
10427 |
10428 | default:
10429 | 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 ))
10430 | 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 ))
10431 | 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 ))
10432 | 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 ));
10433 | break;
10434 | }
10435 | }
10436 |
10437 | static void
10438 | fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos)
10439 | {
10440 | char *p;
10441 | int bitfield_byte_length = 0, bitwidth;
10442 | uint64_t unshifted_value;
10443 | uint64_t value;
10444 |
10445 | const header_field_info *hfinfo = fi->hfinfo;
10446 |
10447 | value = fvalue_get_uinteger64(fi->value);
10448 | if (hfinfo->bitmask) {
10449 | /* Figure out the bit width */
10450 | bitwidth = hfinfo_container_bitwidth(hfinfo);
10451 |
10452 | /* Un-shift bits */
10453 | unshifted_value = value;
10454 | unshifted_value <<= hfinfo_bitshift(hfinfo);
10455 |
10456 | /* Create the bitfield first */
10457 | p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10458 | bitfield_byte_length = (int) (p - label_str);
10459 | }
10460 |
10461 | /* Fill in the textual info */
10462 | label_fill(label_str, bitfield_byte_length, hfinfo, tfs_get_string(!!value, hfinfo->strings), value_pos);
10463 | }
10464 |
10465 | static const char *
10466 | hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo)
10467 | {
10468 | if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10469 | return try_rval_to_str(value, (const range_string *) hfinfo->strings);
10470 |
10471 | if (hfinfo->display & BASE_EXT_STRING0x00000200) {
10472 | if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10473 | return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10474 | else
10475 | return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
10476 | }
10477 |
10478 | if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10479 | return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10480 |
10481 | if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10482 | return unit_name_string_get_value(value, (const struct unit_name_string*) hfinfo->strings);
10483 |
10484 | return try_val_to_str(value, (const value_string *) hfinfo->strings);
10485 | }
10486 |
10487 | static const char *
10488 | hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo)
10489 | {
10490 | if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
10491 | if (hfinfo->display & BASE_EXT_STRING0x00000200)
10492 | return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10493 | else
10494 | return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10495 | }
10496 |
10497 | if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10498 | return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
10499 |
10500 | if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10501 | return unit_name_string_get_value64(value, (const struct unit_name_string*) hfinfo->strings);
10502 |
10503 | /* If this is reached somebody registered a 64-bit field with a 32-bit
10504 | * value-string, which isn't right. */
10505 | 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)
10506 | hfinfo->abbrev)proto_report_dissector_bug("field %s is a 64-bit field with a 32-bit value_string" , hfinfo->abbrev);
10507 |
10508 | /* This is necessary to squelch MSVC errors; is there
10509 | any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10510 | never returns? */
10511 | return NULL((void*)0);
10512 | }
10513 |
10514 | static const char *
10515 | hf_try_double_val_to_str(double value, const header_field_info *hfinfo)
10516 | {
10517 | if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10518 | return unit_name_string_get_double(value, (const struct unit_name_string*)hfinfo->strings);
10519 |
10520 | 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);
10521 |
10522 | /* This is necessary to squelch MSVC errors; is there
10523 | any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10524 | never returns? */
10525 | return NULL((void*)0);
10526 | }
10527 |
10528 | static const char *
10529 | hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str)
10530 | {
10531 | const char *str = hf_try_val_to_str(value, hfinfo);
10532 |
10533 | return (str) ? str : unknown_str;
10534 | }
10535 |
10536 | static const char *
10537 | hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str)
10538 | {
10539 | const char *str = hf_try_val64_to_str(value, hfinfo);
10540 |
10541 | return (str) ? str : unknown_str;
10542 | }
10543 |
10544 | /* Fills data for bitfield chars with val_strings */
10545 | static void
10546 | fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos)
10547 | {
10548 | char *p;
10549 | int bitfield_byte_length, bitwidth;
10550 | uint32_t unshifted_value;
10551 | uint32_t value;
10552 |
10553 | char buf[32];
10554 | const char *out;
10555 |
10556 | const header_field_info *hfinfo = fi->hfinfo;
10557 |
10558 | /* Figure out the bit width */
10559 | bitwidth = hfinfo_container_bitwidth(hfinfo);
10560 |
10561 | /* Un-shift bits */
10562 | value = fvalue_get_uinteger(fi->value);
10563 |
10564 | unshifted_value = value;
10565 | if (hfinfo->bitmask) {
10566 | unshifted_value <<= hfinfo_bitshift(hfinfo);
10567 | }
10568 |
10569 | /* Create the bitfield first */
10570 | p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10571 | bitfield_byte_length = (int) (p - label_str);
10572 |
10573 | /* Fill in the textual info using stored (shifted) value */
10574 | if (hfinfo->display == BASE_CUSTOM) {
10575 | char tmp[ITEM_LABEL_LENGTH240];
10576 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10577 |
10578 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 10578, "fmtfunc"))));
10579 | fmtfunc(tmp, value);
10580 | label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10581 | }
10582 | else if (hfinfo->strings) {
10583 | const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10584 |
10585 | out = hfinfo_char_vals_format(hfinfo, buf, value);
10586 | if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10587 | label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10588 | else
10589 | label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10590 | }
10591 | else {
10592 | out = hfinfo_char_value_format(hfinfo, buf, value);
10593 |
10594 | label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10595 | }
10596 | }
10597 |
10598 | /* Fills data for bitfield ints with val_strings */
10599 | static void
10600 | fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10601 | {
10602 | char *p;
10603 | int bitfield_byte_length, bitwidth;
10604 | uint32_t value, unshifted_value;
10605 | char buf[NUMBER_LABEL_LENGTH80];
10606 | const char *out;
10607 |
10608 | const header_field_info *hfinfo = fi->hfinfo;
10609 |
10610 | /* Figure out the bit width */
10611 | if (fi->flags & FI_VARINT0x00040000)
10612 | bitwidth = fi->length*8;
10613 | else
10614 | bitwidth = hfinfo_container_bitwidth(hfinfo);
10615 |
10616 | /* Un-shift bits */
10617 | if (is_signed)
10618 | value = fvalue_get_sinteger(fi->value);
10619 | else
10620 | value = fvalue_get_uinteger(fi->value);
10621 |
10622 | unshifted_value = value;
10623 | if (hfinfo->bitmask) {
10624 | unshifted_value <<= hfinfo_bitshift(hfinfo);
10625 | }
10626 |
10627 | /* Create the bitfield first */
10628 | if (fi->flags & FI_VARINT0x00040000)
10629 | p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10630 | else
10631 | p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10632 | bitfield_byte_length = (int) (p - label_str);
10633 |
10634 | /* Fill in the textual info using stored (shifted) value */
10635 | if (hfinfo->display == BASE_CUSTOM) {
10636 | char tmp[ITEM_LABEL_LENGTH240];
10637 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10638 |
10639 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 10639, "fmtfunc"))));
10640 | fmtfunc(tmp, value);
10641 | label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10642 | }
10643 | else if (hfinfo->strings) {
10644 | const char *val_str = hf_try_val_to_str(value, hfinfo);
10645 |
10646 | out = hfinfo_number_vals_format(hfinfo, buf, value);
10647 | if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10648 | /*
10649 | * Unique values only display value_string string
10650 | * if there is a match. Otherwise it's just a number
10651 | */
10652 | if (val_str) {
10653 | label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10654 | } else {
10655 | label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10656 | }
10657 | } else {
10658 | if (val_str == NULL((void*)0))
10659 | val_str = "Unknown";
10660 |
10661 | if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10662 | label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10663 | else
10664 | label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10665 | }
10666 | }
10667 | else {
10668 | out = hfinfo_number_value_format(hfinfo, buf, value);
10669 |
10670 | label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10671 | }
10672 | }
10673 |
10674 | static void
10675 | fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10676 | {
10677 | char *p;
10678 | int bitfield_byte_length, bitwidth;
10679 | uint64_t value, unshifted_value;
10680 | char buf[NUMBER_LABEL_LENGTH80];
10681 | const char *out;
10682 |
10683 | const header_field_info *hfinfo = fi->hfinfo;
10684 |
10685 | /* Figure out the bit width */
10686 | if (fi->flags & FI_VARINT0x00040000)
10687 | bitwidth = fi->length*8;
10688 | else
10689 | bitwidth = hfinfo_container_bitwidth(hfinfo);
10690 |
10691 | /* Un-shift bits */
10692 | if (is_signed)
10693 | value = fvalue_get_sinteger64(fi->value);
10694 | else
10695 | value = fvalue_get_uinteger64(fi->value);
10696 |
10697 | unshifted_value = value;
10698 | if (hfinfo->bitmask) {
10699 | unshifted_value <<= hfinfo_bitshift(hfinfo);
10700 | }
10701 |
10702 | /* Create the bitfield first */
10703 | if (fi->flags & FI_VARINT0x00040000)
10704 | p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10705 | else
10706 | p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10707 | bitfield_byte_length = (int) (p - label_str);
10708 |
10709 | /* Fill in the textual info using stored (shifted) value */
10710 | if (hfinfo->display == BASE_CUSTOM) {
10711 | char tmp[ITEM_LABEL_LENGTH240];
10712 | const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10713 |
10714 | DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug( "%s:%u: failed assertion \"%s\"", "epan/proto.c", 10714, "fmtfunc64" ))));
10715 | fmtfunc64(tmp, value);
10716 | label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10717 | }
10718 | else if (hfinfo->strings) {
10719 | const char *val_str = hf_try_val64_to_str(value, hfinfo);
10720 |
10721 | out = hfinfo_number_vals_format64(hfinfo, buf, value);
10722 | if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10723 | /*
10724 | * Unique values only display value_string string
10725 | * if there is a match. Otherwise it's just a number
10726 | */
10727 | if (val_str) {
10728 | label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10729 | } else {
10730 | label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10731 | }
10732 | } else {
10733 | if (val_str == NULL((void*)0))
10734 | val_str = "Unknown";
10735 |
10736 | if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10737 | label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10738 | else
10739 | label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10740 | }
10741 | }
10742 | else {
10743 | out = hfinfo_number_value_format64(hfinfo, buf, value);
10744 |
10745 | label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10746 | }
10747 | }
10748 |
10749 | static void
10750 | fill_label_char(const field_info *fi, char *label_str, size_t *value_pos)
10751 | {
10752 | const header_field_info *hfinfo = fi->hfinfo;
10753 | uint32_t value;
10754 |
10755 | char buf[32];
10756 | const char *out;
10757 |
10758 | value = fvalue_get_uinteger(fi->value);
10759 |
10760 | /* Fill in the textual info */
10761 | if (hfinfo->display == BASE_CUSTOM) {
10762 | char tmp[ITEM_LABEL_LENGTH240];
10763 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10764 |
10765 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 10765, "fmtfunc"))));
10766 | fmtfunc(tmp, value);
10767 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10768 | }
10769 | else if (hfinfo->strings) {
10770 | const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10771 |
10772 | out = hfinfo_char_vals_format(hfinfo, buf, value);
10773 | label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10774 | }
10775 | else {
10776 | out = hfinfo_char_value_format(hfinfo, buf, value);
10777 |
10778 | label_fill(label_str, 0, hfinfo, out, value_pos);
10779 | }
10780 | }
10781 |
10782 | static void
10783 | fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10784 | {
10785 | const header_field_info *hfinfo = fi->hfinfo;
10786 | uint32_t value;
10787 |
10788 | char buf[NUMBER_LABEL_LENGTH80];
10789 | const char *out;
10790 |
10791 | if (is_signed)
10792 | value = fvalue_get_sinteger(fi->value);
10793 | else
10794 | value = fvalue_get_uinteger(fi->value);
10795 |
10796 | /* Fill in the textual info */
10797 | if (hfinfo->display == BASE_CUSTOM) {
10798 | char tmp[ITEM_LABEL_LENGTH240];
10799 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10800 |
10801 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 10801, "fmtfunc"))));
10802 | fmtfunc(tmp, value);
10803 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10804 | }
10805 | else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
10806 | /*
10807 | * It makes no sense to have a value-string table for a
10808 | * frame-number field - they're just integers giving
10809 | * the ordinal frame number.
10810 | */
10811 | const char *val_str = hf_try_val_to_str(value, hfinfo);
10812 |
10813 | out = hfinfo_number_vals_format(hfinfo, buf, value);
10814 | if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10815 | /*
10816 | * Unique values only display value_string string
10817 | * if there is a match. Otherwise it's just a number
10818 | */
10819 | if (val_str) {
10820 | label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10821 | } else {
10822 | label_fill(label_str, 0, hfinfo, out, value_pos);
10823 | }
10824 | } else {
10825 | if (val_str == NULL((void*)0))
10826 | val_str = "Unknown";
10827 |
10828 | if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10829 | label_fill(label_str, 0, hfinfo, val_str, value_pos);
10830 | else
10831 | label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10832 | }
10833 | }
10834 | 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 ))) {
10835 | char tmp[ITEM_LABEL_LENGTH240];
10836 |
10837 | port_with_resolution_to_str_buf(tmp, sizeof(tmp),
10838 | display_to_port_type((field_display_e)hfinfo->display), value);
10839 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10840 | }
10841 | else {
10842 | out = hfinfo_number_value_format(hfinfo, buf, value);
10843 |
10844 | label_fill(label_str, 0, hfinfo, out, value_pos);
10845 | }
10846 | }
10847 |
10848 | static void
10849 | fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10850 | {
10851 | const header_field_info *hfinfo = fi->hfinfo;
10852 | uint64_t value;
10853 |
10854 | char buf[NUMBER_LABEL_LENGTH80];
10855 | const char *out;
10856 |
10857 | if (is_signed)
10858 | value = fvalue_get_sinteger64(fi->value);
10859 | else
10860 | value = fvalue_get_uinteger64(fi->value);
10861 |
10862 | /* Fill in the textual info */
10863 | if (hfinfo->display == BASE_CUSTOM) {
10864 | char tmp[ITEM_LABEL_LENGTH240];
10865 | const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10866 |
10867 | DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug( "%s:%u: failed assertion \"%s\"", "epan/proto.c", 10867, "fmtfunc64" ))));
10868 | fmtfunc64(tmp, value);
10869 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10870 | }
10871 | else if (hfinfo->strings) {
10872 | const char *val_str = hf_try_val64_to_str(value, hfinfo);
10873 |
10874 | out = hfinfo_number_vals_format64(hfinfo, buf, value);
10875 | if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10876 | /*
10877 | * Unique values only display value_string string
10878 | * if there is a match. Otherwise it's just a number
10879 | */
10880 | if (val_str) {
10881 | label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10882 | } else {
10883 | label_fill(label_str, 0, hfinfo, out, value_pos);
10884 | }
10885 | } else {
10886 | if (val_str == NULL((void*)0))
10887 | val_str = "Unknown";
10888 |
10889 | if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10890 | label_fill(label_str, 0, hfinfo, val_str, value_pos);
10891 | else
10892 | label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10893 | }
10894 | }
10895 | else {
10896 | out = hfinfo_number_value_format64(hfinfo, buf, value);
10897 |
10898 | label_fill(label_str, 0, hfinfo, out, value_pos);
10899 | }
10900 | }
10901 |
10902 | static size_t
10903 | fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size)
10904 | {
10905 | int display;
10906 | int n;
10907 | double value;
10908 |
10909 | if (label_str_size < 12) {
10910 | /* Not enough room to write an entire floating point value. */
10911 | return 0;
10912 | }
10913 |
10914 | display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
10915 | value = fvalue_get_floating(fi->value);
10916 |
10917 | if (display == BASE_CUSTOM) {
10918 | const custom_fmt_func_double_t fmtfunc = (const custom_fmt_func_double_t)fi->hfinfo->strings;
10919 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 10919, "fmtfunc"))));
10920 | fmtfunc(label_str, value);
10921 | return strlen(label_str);
10922 | }
10923 |
10924 | switch (display) {
10925 | case BASE_NONE:
10926 | if (fi->hfinfo->type == FT_FLOAT) {
10927 | n = snprintf(label_str, label_str_size, "%.*g", FLT_DIG6, value);
10928 | } else {
10929 | n = (int)strlen(dtoa_g_fmt(label_str, value));
10930 | }
10931 | break;
10932 | case BASE_DEC:
10933 | n = snprintf(label_str, label_str_size, "%f", value);
10934 | break;
10935 | case BASE_HEX:
10936 | n = snprintf(label_str, label_str_size, "%a", value);
10937 | break;
10938 | case BASE_EXP:
10939 | n = snprintf(label_str, label_str_size, "%e", value);
10940 | break;
10941 | default:
10942 | ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10942 , __func__, "assertion \"not reached\" failed");
10943 | }
10944 | if (n < 0) {
10945 | return 0; /* error */
10946 | }
10947 | if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
10948 | const char *hf_str_val;
10949 | hf_str_val = hf_try_double_val_to_str(value, fi->hfinfo);
10950 | n += proto_strlcpy(label_str + n, hf_str_val, label_str_size - n);
10951 | }
10952 | if (n > label_str_size) {
10953 | ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 10953, __func__, "label length too small"); } } while (0);
10954 | return strlen(label_str);
10955 | }
10956 |
10957 | return n;
10958 | }
10959 |
10960 | void
10961 | fill_label_float(const field_info *fi, char *label_str, size_t *value_pos)
10962 | {
10963 | char tmp[ITEM_LABEL_LENGTH240];
10964 |
10965 | fill_display_label_float(fi, tmp, ITEM_LABEL_LENGTH240);
10966 | label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
10967 | }
10968 |
10969 | static size_t
10970 | fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size)
10971 | {
10972 | int display;
10973 | size_t pos = 0;
10974 | double value;
10975 | char* tmp_str;
10976 |
10977 | if (label_str_size < 12) {
10978 | /* Not enough room to write an entire floating point value. */
10979 | return 0;
10980 | }
10981 |
10982 | display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
10983 | tmp_str = fvalue_to_string_repr(NULL((void*)0), fi->value, FTREPR_DISPLAY, display);
10984 | pos = label_concat(label_str, pos, (const uint8_t*)tmp_str)ws_label_strcpy(label_str, 240, pos, (const uint8_t*)tmp_str, 0);
10985 | wmem_free(NULL((void*)0), tmp_str);
10986 |
10987 | if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
10988 | const char *hf_str_val;
10989 | fvalue_to_double(fi->value, &value);
10990 | hf_str_val = unit_name_string_get_double(value, (const struct unit_name_string*)fi->hfinfo->strings);
10991 | 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);
10992 | }
10993 | if ((int)pos > label_str_size) {
10994 | ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 10994, __func__, "label length too small"); } } while (0);
10995 | return strlen(label_str);
10996 | }
10997 |
10998 | return pos;
10999 | }
11000 |
11001 | void
11002 | fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos)
11003 | {
11004 | char tmp[ITEM_LABEL_LENGTH240];
11005 |
11006 | fill_display_label_ieee_11073_float(fi, tmp, ITEM_LABEL_LENGTH240);
11007 | label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
11008 | }
11009 |
11010 | int
11011 | hfinfo_bitshift(const header_field_info *hfinfo)
11012 | {
11013 | return ws_ctz(hfinfo->bitmask);
11014 | }
11015 |
11016 |
11017 | static int
11018 | hfinfo_bitoffset(const header_field_info *hfinfo)
11019 | {
11020 | if (!hfinfo->bitmask) {
11021 | return 0;
11022 | }
11023 |
11024 | /* ilog2 = first set bit, counting 0 as the last bit; we want 0
11025 | * as the first bit */
11026 | return hfinfo_container_bitwidth(hfinfo) - 1 - ws_ilog2(hfinfo->bitmask);
11027 | }
11028 |
11029 | static int
11030 | hfinfo_mask_bitwidth(const header_field_info *hfinfo)
11031 | {
11032 | if (!hfinfo->bitmask) {
11033 | return 0;
11034 | }
11035 |
11036 | /* ilog2 = first set bit, ctz = last set bit */
11037 | return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
11038 | }
11039 |
11040 | static int
11041 | hfinfo_type_bitwidth(enum ftenum type)
11042 | {
11043 | int bitwidth = 0;
11044 |
11045 | switch (type) {
11046 | case FT_CHAR:
11047 | case FT_UINT8:
11048 | case FT_INT8:
11049 | bitwidth = 8;
11050 | break;
11051 | case FT_UINT16:
11052 | case FT_INT16:
11053 | bitwidth = 16;
11054 | break;
11055 | case FT_UINT24:
11056 | case FT_INT24:
11057 | bitwidth = 24;
11058 | break;
11059 | case FT_UINT32:
11060 | case FT_INT32:
11061 | bitwidth = 32;
11062 | break;
11063 | case FT_UINT40:
11064 | case FT_INT40:
11065 | bitwidth = 40;
11066 | break;
11067 | case FT_UINT48:
11068 | case FT_INT48:
11069 | bitwidth = 48;
11070 | break;
11071 | case FT_UINT56:
11072 | case FT_INT56:
11073 | bitwidth = 56;
11074 | break;
11075 | case FT_UINT64:
11076 | case FT_INT64:
11077 | bitwidth = 64;
11078 | break;
11079 | default:
11080 | DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\"" , "epan/proto.c", 11080));
11081 | ;
11082 | }
11083 | return bitwidth;
11084 | }
11085 |
11086 |
11087 | static int
11088 | hfinfo_container_bitwidth(const header_field_info *hfinfo)
11089 | {
11090 | if (!hfinfo->bitmask) {
11091 | return 0;
11092 | }
11093 |
11094 | if (hfinfo->type == FT_BOOLEAN) {
11095 | return hfinfo->display; /* hacky? :) */
11096 | }
11097 |
11098 | return hfinfo_type_bitwidth(hfinfo->type);
11099 | }
11100 |
11101 | static int
11102 | hfinfo_hex_digits(const header_field_info *hfinfo)
11103 | {
11104 | int bitwidth;
11105 |
11106 | /* If we have a bitmask, hfinfo->type is the width of the container, so not
11107 | * appropriate to determine the number of hex digits for the field.
11108 | * So instead, we compute it from the bitmask.
11109 | */
11110 | if (hfinfo->bitmask != 0) {
11111 | bitwidth = hfinfo_mask_bitwidth(hfinfo);
11112 | } else {
11113 | bitwidth = hfinfo_type_bitwidth(hfinfo->type);
11114 | }
11115 |
11116 | /* Divide by 4, rounding up, to get number of hex digits. */
11117 | return (bitwidth + 3) / 4;
11118 | }
11119 |
11120 | const char *
11121 | hfinfo_char_value_format_display(int display, char buf[7], uint32_t value)
11122 | {
11123 | char *ptr = &buf[6];
11124 | static const char hex_digits[16] =
11125 | { '0', '1', '2', '3', '4', '5', '6', '7',
11126 | '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
11127 |
11128 | *ptr = '\0';
11129 | *(--ptr) = '\'';
11130 | /* Properly format value */
11131 | if (g_ascii_isprint(value)((g_ascii_table[(guchar) (value)] & G_ASCII_PRINT) != 0)) {
11132 | /*
11133 | * Printable, so just show the character, and, if it needs
11134 | * to be escaped, escape it.
11135 | */
11136 | *(--ptr) = value;
11137 | if (value == '\\' || value == '\'')
11138 | *(--ptr) = '\\';
11139 | } else {
11140 | /*
11141 | * Non-printable; show it as an escape sequence.
11142 | */
11143 | switch (value) {
11144 |
11145 | case '\0':
11146 | /*
11147 | * Show a NUL with only one digit.
11148 | */
11149 | *(--ptr) = '0';
11150 | break;
11151 |
11152 | case '\a':
11153 | case '\b':
11154 | case '\f':
11155 | case '\n':
11156 | case '\r':
11157 | case '\t':
11158 | case '\v':
11159 | *(--ptr) = value - '\a' + 'a';
11160 | break;
11161 |
11162 | default:
11163 | switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11164 |
11165 | case BASE_OCT:
11166 | *(--ptr) = (value & 0x7) + '0';
11167 | value >>= 3;
11168 | *(--ptr) = (value & 0x7) + '0';
11169 | value >>= 3;
11170 | *(--ptr) = (value & 0x7) + '0';
11171 | break;
11172 |
11173 | case BASE_HEX:
11174 | *(--ptr) = hex_digits[value & 0x0F];
11175 | value >>= 4;
11176 | *(--ptr) = hex_digits[value & 0x0F];
11177 | *(--ptr) = 'x';
11178 | break;
11179 |
11180 | default:
11181 | REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) & 0xFF));
11182 | }
11183 | }
11184 | *(--ptr) = '\\';
11185 | }
11186 | *(--ptr) = '\'';
11187 | return ptr;
11188 | }
11189 |
11190 | static const char *
11191 | hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11192 | {
11193 | char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11194 | 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 ));
11195 |
11196 | *ptr = '\0';
11197 | /* Properly format value */
11198 | switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11199 | case BASE_DEC:
11200 | return isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11201 |
11202 | case BASE_DEC_HEX:
11203 | *(--ptr) = ')';
11204 | ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11205 | *(--ptr) = '(';
11206 | *(--ptr) = ' ';
11207 | ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11208 | return ptr;
11209 |
11210 | case BASE_OCT:
11211 | return oct_to_str_back(ptr, value);
11212 |
11213 | case BASE_HEX:
11214 | return hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11215 |
11216 | case BASE_HEX_DEC:
11217 | *(--ptr) = ')';
11218 | ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11219 | *(--ptr) = '(';
11220 | *(--ptr) = ' ';
11221 | ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11222 | return ptr;
11223 |
11224 | case BASE_PT_UDP:
11225 | case BASE_PT_TCP:
11226 | case BASE_PT_DCCP:
11227 | case BASE_PT_SCTP:
11228 | port_with_resolution_to_str_buf(buf, NUMBER_LABEL_LENGTH80,
11229 | display_to_port_type((field_display_e)display), value);
11230 | return buf;
11231 | case BASE_OUI:
11232 | {
11233 | uint8_t p_oui[3];
11234 | const char *manuf_name;
11235 |
11236 | p_oui[0] = value >> 16 & 0xFF;
11237 | p_oui[1] = value >> 8 & 0xFF;
11238 | p_oui[2] = value & 0xFF;
11239 |
11240 | /* Attempt an OUI lookup. */
11241 | manuf_name = uint_get_manuf_name_if_known(value);
11242 | if (manuf_name == NULL((void*)0)) {
11243 | /* Could not find an OUI. */
11244 | snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x", p_oui[0], p_oui[1], p_oui[2]);
11245 | }
11246 | else {
11247 | /* Found an address string. */
11248 | snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x (%s)", p_oui[0], p_oui[1], p_oui[2], manuf_name);
11249 | }
11250 | return buf;
11251 | }
11252 |
11253 | default:
11254 | REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) & 0xFF));
11255 | }
11256 | return ptr;
11257 | }
11258 |
11259 | static const char *
11260 | hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11261 | {
11262 | char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11263 | 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 ));
11264 |
11265 | *ptr = '\0';
11266 | /* Properly format value */
11267 | switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11268 | case BASE_DEC:
11269 | return isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11270 |
11271 | case BASE_DEC_HEX:
11272 | *(--ptr) = ')';
11273 | ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11274 | *(--ptr) = '(';
11275 | *(--ptr) = ' ';
11276 | ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11277 | return ptr;
11278 |
11279 | case BASE_OCT:
11280 | return oct64_to_str_back(ptr, value);
11281 |
11282 | case BASE_HEX:
11283 | return hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11284 |
11285 | case BASE_HEX_DEC:
11286 | *(--ptr) = ')';
11287 | ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11288 | *(--ptr) = '(';
11289 | *(--ptr) = ' ';
11290 | ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11291 | return ptr;
11292 |
11293 | default:
11294 | REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) & 0xFF));
11295 | }
11296 |
11297 | return ptr;
11298 | }
11299 |
11300 | static const char *
11301 | hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11302 | {
11303 | int display = hfinfo->display;
11304 |
11305 | if (hfinfo->type == FT_FRAMENUM) {
11306 | /*
11307 | * Frame numbers are always displayed in decimal.
11308 | */
11309 | display = BASE_DEC;
11310 | }
11311 |
11312 | return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11313 | }
11314 |
11315 | static const char *
11316 | hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11317 | {
11318 | int display = hfinfo->display;
11319 |
11320 | if (hfinfo->type == FT_FRAMENUM) {
11321 | /*
11322 | * Frame numbers are always displayed in decimal.
11323 | */
11324 | display = BASE_DEC;
11325 | }
11326 |
11327 | return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11328 | }
11329 |
11330 | static const char *
11331 | hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11332 | {
11333 | /* Get the underlying BASE_ value */
11334 | int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11335 |
11336 | return hfinfo_char_value_format_display(display, buf, value);
11337 | }
11338 |
11339 | static const char *
11340 | hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11341 | {
11342 | /* Get the underlying BASE_ value */
11343 | int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11344 |
11345 | if (hfinfo->type == FT_FRAMENUM) {
11346 | /*
11347 | * Frame numbers are always displayed in decimal.
11348 | */
11349 | display = BASE_DEC;
11350 | }
11351 |
11352 | if (IS_BASE_PORT(display)(((display)==BASE_PT_UDP||(display)==BASE_PT_TCP||(display)== BASE_PT_DCCP||(display)==BASE_PT_SCTP))) {
11353 | display = BASE_DEC;
11354 | } else if (display == BASE_OUI) {
11355 | display = BASE_HEX;
11356 | }
11357 |
11358 | switch (display) {
11359 | case BASE_NONE:
11360 | /* case BASE_DEC: */
11361 | case BASE_DEC_HEX:
11362 | case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11363 | case BASE_CUSTOM:
11364 | display = BASE_DEC;
11365 | break;
11366 |
11367 | /* case BASE_HEX: */
11368 | case BASE_HEX_DEC:
11369 | display = BASE_HEX;
11370 | break;
11371 | }
11372 |
11373 | return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11374 | }
11375 |
11376 | static const char *
11377 | hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11378 | {
11379 | /* Get the underlying BASE_ value */
11380 | int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11381 |
11382 | if (hfinfo->type == FT_FRAMENUM) {
11383 | /*
11384 | * Frame numbers are always displayed in decimal.
11385 | */
11386 | display = BASE_DEC;
11387 | }
11388 |
11389 | switch (display) {
11390 | case BASE_NONE:
11391 | /* case BASE_DEC: */
11392 | case BASE_DEC_HEX:
11393 | case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11394 | case BASE_CUSTOM:
11395 | display = BASE_DEC;
11396 | break;
11397 |
11398 | /* case BASE_HEX: */
11399 | case BASE_HEX_DEC:
11400 | display = BASE_HEX;
11401 | break;
11402 | }
11403 |
11404 | return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11405 | }
11406 |
11407 | static const char *
11408 | hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11409 | {
11410 | /* Get the underlying BASE_ value */
11411 | int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11412 |
11413 | return hfinfo_char_value_format_display(display, buf, value);
11414 | }
11415 |
11416 | static const char *
11417 | hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11418 | {
11419 | /* Get the underlying BASE_ value */
11420 | int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11421 |
11422 | if (display == BASE_NONE)
11423 | return NULL((void*)0);
11424 |
11425 | if (display == BASE_DEC_HEX)
11426 | display = BASE_DEC;
11427 | if (display == BASE_HEX_DEC)
11428 | display = BASE_HEX;
11429 |
11430 | return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11431 | }
11432 |
11433 | static const char *
11434 | hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11435 | {
11436 | /* Get the underlying BASE_ value */
11437 | int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11438 |
11439 | if (display == BASE_NONE)
11440 | return NULL((void*)0);
11441 |
11442 | if (display == BASE_DEC_HEX)
11443 | display = BASE_DEC;
11444 | if (display == BASE_HEX_DEC)
11445 | display = BASE_HEX;
11446 |
11447 | return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11448 | }
11449 |
11450 | const char *
11451 | proto_registrar_get_name(const int n)
11452 | {
11453 | header_field_info *hfinfo;
11454 |
11455 | PROTO_REGISTRAR_GET_NTH(n, hfinfo)if((n == 0 || (unsigned)n > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug ) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 11455 , __func__, "Unregistered hf! index=%d", n); ((void) ((n > 0 && (unsigned)n < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 11455 , "n > 0 && (unsigned)n < gpa_hfinfo.len", "Unregistered hf!" )))) ; ((void) ((gpa_hfinfo.hfi[n] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 11455, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[n];;
11456 | return hfinfo->name;
11457 | }
11458 |
11459 | const char *
11460 | proto_registrar_get_abbrev(const int n)
11461 | {
11462 | header_field_info *hfinfo;
11463 |
11464 | PROTO_REGISTRAR_GET_NTH(n, hfinfo)if((n == 0 || (unsigned)n > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug ) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 11464 , __func__, "Unregistered hf! index=%d", n); ((void) ((n > 0 && (unsigned)n < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 11464 , "n > 0 && (unsigned)n < gpa_hfinfo.len", "Unregistered hf!" )))) ; ((void) ((gpa_hfinfo.hfi[n] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 11464, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[n];;
11465 | return hfinfo->abbrev;
11466 | }
11467 |
11468 | enum ftenum
11469 | proto_registrar_get_ftype(const int n)
11470 | {
11471 | header_field_info *hfinfo;
11472 |
11473 | 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", 11473 , __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", 11473 , "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", 11473, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[n];;
11474 | return hfinfo->type;
11475 | }
11476 |
11477 | int
11478 | proto_registrar_get_parent(const int n)
11479 | {
11480 | header_field_info *hfinfo;
11481 |
11482 | 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", 11482 , __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", 11482 , "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", 11482, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[n];;
11483 | return hfinfo->parent;
11484 | }
11485 |
11486 | bool_Bool
11487 | proto_registrar_is_protocol(const int n)
11488 | {
11489 | header_field_info *hfinfo;
11490 |
11491 | 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", 11491 , __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", 11491 , "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", 11491, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[n];;
11492 | return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? true1 : false0);
11493 | }
11494 |
11495 | /* Returns length of field in packet (not necessarily the length
11496 | * in our internal representation, as in the case of IPv4).
11497 | * 0 means undeterminable at time of registration
11498 | * -1 means the field is not registered. */
11499 | int
11500 | proto_registrar_get_length(const int n)
11501 | {
11502 | header_field_info *hfinfo;
11503 |
11504 | 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", 11504 , __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", 11504 , "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", 11504, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[n];;
11505 | return ftype_wire_size(hfinfo->type);
11506 | }
11507 |
11508 | size_t
11509 | proto_registrar_get_count(struct proto_registrar_stats *stats)
11510 | {
11511 | header_field_info *hfinfo;
11512 |
11513 | // Index zero is not used. We have to skip it.
11514 | size_t total_count = gpa_hfinfo.len - 1;
11515 | if (stats == NULL((void*)0)) {
11516 | return total_count;
11517 | }
11518 | for (uint32_t id = 1; id < gpa_hfinfo.len; id++) {
11519 | if (gpa_hfinfo.hfi[id] == NULL((void*)0)) {
11520 | stats->deregistered_count++;
11521 | continue; /* This is a deregistered protocol or header field */
11522 | }
11523 |
11524 | PROTO_REGISTRAR_GET_NTH(id, hfinfo)if((id == 0 || (unsigned)id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug ) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 11524 , __func__, "Unregistered hf! index=%d", id); ((void) ((id > 0 && (unsigned)id < gpa_hfinfo.len) ? (void)0 : ( proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 11524, "id > 0 && (unsigned)id < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[id] != (( void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 11524, "gpa_hfinfo.hfi[id] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[id];;
11525 |
11526 | if (proto_registrar_is_protocol(id))
11527 | stats->protocol_count++;
11528 |
11529 | if (hfinfo->same_name_prev_id != -1)
11530 | stats->same_name_count++;
11531 | }
11532 |
11533 | return total_count;
11534 | }
11535 |
11536 | /* Looks for a protocol or a field in a proto_tree. Returns true if
11537 | * it exists anywhere, or false if it exists nowhere. */
11538 | bool_Bool
11539 | proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
11540 | {
11541 | GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
11542 |
11543 | if (g_ptr_array_len(ptrs)((ptrs) ? (ptrs)->len : 0) > 0) {
11544 | return true1;
11545 | }
11546 | else {
11547 | return false0;
11548 | }
11549 | }
11550 |
11551 | /* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
11552 | * This only works if the hfindex was "primed" before the dissection
11553 | * took place, as we just pass back the already-created GPtrArray*.
11554 | * The caller should *not* free the GPtrArray*; proto_tree_free_node()
11555 | * handles that. */
11556 | GPtrArray *
11557 | proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
11558 | {
11559 | if (!tree)
11560 | return NULL((void*)0);
11561 |
11562 | if (PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids != NULL((void*)0))
11563 | return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids,
11564 | GINT_TO_POINTER(id)((gpointer) (glong) (id)));
11565 | else
11566 | return NULL((void*)0);
11567 | }
11568 |
11569 | bool_Bool
11570 | proto_tracking_interesting_fields(const proto_tree *tree)
11571 | {
11572 | GHashTable *interesting_hfids;
11573 |
11574 | if (!tree)
11575 | return false0;
11576 |
11577 | interesting_hfids = PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids;
11578 |
11579 | return (interesting_hfids != NULL((void*)0)) && g_hash_table_size(interesting_hfids);
11580 | }
11581 |
11582 | /* Helper struct for proto_find_info() and proto_all_finfos() */
11583 | typedef struct {
11584 | GPtrArray *array;
11585 | int id;
11586 | } ffdata_t;
11587 |
11588 | /* Helper function for proto_find_info() */
11589 | static bool_Bool
11590 | find_finfo(proto_node *node, void * data)
11591 | {
11592 | field_info *fi = PNODE_FINFO(node)((node)->finfo);
11593 | if (fi && fi->hfinfo) {
11594 | if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11595 | g_ptr_array_add(((ffdata_t*)data)->array, fi);
11596 | }
11597 | }
11598 |
11599 | /* Don't stop traversing. */
11600 | return false0;
11601 | }
11602 |
11603 | /* Helper function for proto_find_first_info() */
11604 | static bool_Bool
11605 | find_first_finfo(proto_node *node, void *data)
11606 | {
11607 | field_info *fi = PNODE_FINFO(node)((node)->finfo);
11608 | if (fi && fi->hfinfo) {
11609 | if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11610 | g_ptr_array_add(((ffdata_t*)data)->array, fi);
11611 |
11612 | /* Stop traversing. */
11613 | return true1;
11614 | }
11615 | }
11616 |
11617 | /* Continue traversing. */
11618 | return false0;
11619 | }
11620 |
11621 | /* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
11622 | * This works on any proto_tree, primed or unprimed, but actually searches
11623 | * the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11624 | * The caller does need to free the returned GPtrArray with
11625 | * g_ptr_array_free(<array>, true).
11626 | */
11627 | GPtrArray *
11628 | proto_find_finfo(proto_tree *tree, const int id)
11629 | {
11630 | ffdata_t ffdata;
11631 |
11632 | ffdata.array = g_ptr_array_new();
11633 | ffdata.id = id;
11634 |
11635 | proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
11636 |
11637 | return ffdata.array;
11638 | }
11639 |
11640 | /* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
11641 | * This works on any proto_tree, primed or unprimed, but actually searches
11642 | * the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11643 | * The caller does need to free the returned GPtrArray with
11644 | * g_ptr_array_free(<array>, true).
11645 | */
11646 | GPtrArray *
11647 | proto_find_first_finfo(proto_tree *tree, const int id)
11648 | {
11649 | ffdata_t ffdata;
11650 |
11651 | ffdata.array = g_ptr_array_new();
11652 | ffdata.id = id;
11653 |
11654 | proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
11655 |
11656 | return ffdata.array;
11657 | }
11658 |
11659 | /* Helper function for proto_all_finfos() */
11660 | static bool_Bool
11661 | every_finfo(proto_node *node, void * data)
11662 | {
11663 | field_info *fi = PNODE_FINFO(node)((node)->finfo);
11664 | if (fi && fi->hfinfo) {
11665 | g_ptr_array_add(((ffdata_t*)data)->array, fi);
11666 | }
11667 |
11668 | /* Don't stop traversing. */
11669 | return false0;
11670 | }
11671 |
11672 | /* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree.
11673 | * The caller does need to free the returned GPtrArray with
11674 | * g_ptr_array_free(<array>, true).
11675 | */
11676 | GPtrArray *
11677 | proto_all_finfos(proto_tree *tree)
11678 | {
11679 | ffdata_t ffdata;
11680 |
11681 | /* Pre allocate enough space to hold all fields in most cases */
11682 | ffdata.array = g_ptr_array_sized_new(512);
11683 | ffdata.id = 0;
11684 |
11685 | proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
11686 |
11687 | return ffdata.array;
11688 | }
11689 |
11690 |
11691 | typedef struct {
11692 | unsigned offset;
11693 | field_info *finfo;
11694 | tvbuff_t *tvb;
11695 | } offset_search_t;
11696 |
11697 | static bool_Bool
11698 | check_for_offset(proto_node *node, void * data)
11699 | {
11700 | field_info *fi = PNODE_FINFO(node)((node)->finfo);
11701 | offset_search_t *offsearch = (offset_search_t *)data;
11702 |
11703 | /* !fi == the top most container node which holds nothing */
11704 | if (fi && !proto_item_is_hidden(node) && !proto_item_is_generated(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
11705 | if (offsearch->offset >= (unsigned) fi->start &&
11706 | offsearch->offset < (unsigned) (fi->start + fi->length)) {
11707 |
11708 | offsearch->finfo = fi;
11709 | return false0; /* keep traversing */
11710 | }
11711 | }
11712 | return false0; /* keep traversing */
11713 | }
11714 |
11715 | /* Search a proto_tree backwards (from leaves to root) looking for the field
11716 | * whose start/length occupies 'offset' */
11717 | /* XXX - I couldn't find an easy way to search backwards, so I search
11718 | * forwards, w/o stopping. Therefore, the last finfo I find will the be
11719 | * the one I want to return to the user. This algorithm is inefficient
11720 | * and could be re-done, but I'd have to handle all the children and
11721 | * siblings of each node myself. When I have more time I'll do that.
11722 | * (yeah right) */
11723 | field_info *
11724 | proto_find_field_from_offset(proto_tree *tree, unsigned offset, tvbuff_t *tvb)
11725 | {
11726 | offset_search_t offsearch;
11727 |
11728 | offsearch.offset = offset;
11729 | offsearch.finfo = NULL((void*)0);
11730 | offsearch.tvb = tvb;
11731 |
11732 | proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
11733 |
11734 | return offsearch.finfo;
11735 | }
11736 |
11737 | typedef struct {
11738 | unsigned length;
11739 | char *buf;
11740 | } decoded_data_t;
11741 |
11742 | static bool_Bool
11743 | check_for_undecoded(proto_node *node, void * data)
11744 | {
11745 | field_info *fi = PNODE_FINFO(node)((node)->finfo);
11746 | decoded_data_t* decoded = (decoded_data_t*)data;
11747 | unsigned i;
11748 | unsigned byte;
11749 | unsigned bit;
11750 |
11751 | if (fi && fi->hfinfo->type != FT_PROTOCOL) {
11752 | for (i = fi->start; i < fi->start + fi->length && i < decoded->length; i++) {
11753 | byte = i / 8;
11754 | bit = i % 8;
11755 | decoded->buf[byte] |= (1 << bit);
11756 | }
11757 | }
11758 |
11759 | return false0;
11760 | }
11761 |
11762 | char*
11763 | proto_find_undecoded_data(proto_tree *tree, unsigned length)
11764 | {
11765 | decoded_data_t decoded;
11766 | decoded.length = length;
11767 | decoded.buf = (char*)wmem_alloc0(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), length / 8 + 1);
11768 |
11769 | proto_tree_traverse_pre_order(tree, check_for_undecoded, &decoded);
11770 | return decoded.buf;
11771 | }
11772 |
11773 | /* Dumps the protocols in the registration database to stdout. An independent
11774 | * program can take this output and format it into nice tables or HTML or
11775 | * whatever.
11776 | *
11777 | * There is one record per line. The fields are tab-delimited.
11778 | *
11779 | * Field 1 = protocol name
11780 | * Field 2 = protocol short name
11781 | * Field 3 = protocol filter name
11782 | * Field 4 = protocol enabled
11783 | * Field 5 = protocol enabled by default
11784 | * Field 6 = protocol can toggle
11785 | */
11786 | void
11787 | proto_registrar_dump_protocols(void)
11788 | {
11789 | protocol_t *protocol;
11790 | int i;
11791 | void *cookie = NULL((void*)0);
11792 |
11793 |
11794 | i = proto_get_first_protocol(&cookie);
11795 | while (i != -1) {
11796 | protocol = find_protocol_by_id(i);
11797 | printf("%s\t%s\t%s\t%c\t%c\t%c\n",
11798 | protocol->name,
11799 | protocol->short_name,
11800 | protocol->filter_name,
11801 | (proto_is_protocol_enabled_by_default(protocol) ? 'T' : 'F'),
11802 | (proto_is_protocol_enabled(protocol) ? 'T' : 'F'),
11803 | (proto_can_toggle_protocol(protocol->proto_id) ? 'T' : 'F'));
11804 | i = proto_get_next_protocol(&cookie);
11805 | }
11806 | }
11807 |
11808 | /* Dumps the value_strings, extended value string headers, range_strings
11809 | * or true/false strings for fields that have them.
11810 | * There is one record per line. Fields are tab-delimited.
11811 | * There are four types of records: Value String, Extended Value String Header,
11812 | * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
11813 | * the type of record.
11814 | *
11815 | * Note that a record will be generated only if the value_string,... is referenced
11816 | * in a registered hfinfo entry.
11817 | *
11818 | *
11819 | * Value Strings
11820 | * -------------
11821 | * Field 1 = 'V'
11822 | * Field 2 = Field abbreviation to which this value string corresponds
11823 | * Field 3 = Integer value
11824 | * Field 4 = String
11825 | *
11826 | * Extended Value String Headers
11827 | * -----------------------------
11828 | * Field 1 = 'E'
11829 | * Field 2 = Field abbreviation to which this extended value string header corresponds
11830 | * Field 3 = Extended Value String "Name"
11831 | * Field 4 = Number of entries in the associated value_string array
11832 | * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
11833 | *
11834 | * Range Strings
11835 | * -------------
11836 | * Field 1 = 'R'
11837 | * Field 2 = Field abbreviation to which this range string corresponds
11838 | * Field 3 = Integer value: lower bound
11839 | * Field 4 = Integer value: upper bound
11840 | * Field 5 = String
11841 | *
11842 | * True/False Strings
11843 | * ------------------
11844 | * Field 1 = 'T'
11845 | * Field 2 = Field abbreviation to which this true/false string corresponds
11846 | * Field 3 = True String
11847 | * Field 4 = False String
11848 | */
11849 | void
11850 | proto_registrar_dump_values(void)
11851 | {
11852 | header_field_info *hfinfo;
11853 | int i, len, vi;
11854 | const value_string *vals;
11855 | const val64_string *vals64;
11856 | const range_string *range;
11857 | const true_false_string *tfs;
11858 | const unit_name_string *units;
11859 |
11860 | len = gpa_hfinfo.len;
11861 | for (i = 1; i < len ; i++) {
11862 | if (gpa_hfinfo.hfi[i] == NULL((void*)0))
11863 | continue; /* This is a deregistered protocol or field */
11864 |
11865 | 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", 11865 , __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", 11865 , "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", 11865, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[i];;
11866 |
11867 | if (hfinfo->id == hf_text_only) {
11868 | continue;
11869 | }
11870 |
11871 | /* ignore protocols */
11872 | if (proto_registrar_is_protocol(i)) {
11873 | continue;
11874 | }
11875 | /* process header fields */
11876 | #if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
11877 | /*
11878 | * If this field isn't at the head of the list of
11879 | * fields with this name, skip this field - all
11880 | * fields with the same name are really just versions
11881 | * of the same field stored in different bits, and
11882 | * should have the same type/radix/value list, and
11883 | * just differ in their bit masks. (If a field isn't
11884 | * a bitfield, but can be, say, 1 or 2 bytes long,
11885 | * it can just be made FT_UINT16, meaning the
11886 | * *maximum* length is 2 bytes, and be used
11887 | * for all lengths.)
11888 | */
11889 | if (hfinfo->same_name_prev_id != -1)
11890 | continue;
11891 | #endif
11892 | vals = NULL((void*)0);
11893 | vals64 = NULL((void*)0);
11894 | range = NULL((void*)0);
11895 | tfs = NULL((void*)0);
11896 | units = NULL((void*)0);
11897 |
11898 | if (hfinfo->strings != NULL((void*)0)) {
11899 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM &&
11900 | (hfinfo->type == FT_CHAR ||
11901 | hfinfo->type == FT_UINT8 ||
11902 | hfinfo->type == FT_UINT16 ||
11903 | hfinfo->type == FT_UINT24 ||
11904 | hfinfo->type == FT_UINT32 ||
11905 | hfinfo->type == FT_UINT40 ||
11906 | hfinfo->type == FT_UINT48 ||
11907 | hfinfo->type == FT_UINT56 ||
11908 | hfinfo->type == FT_UINT64 ||
11909 | hfinfo->type == FT_INT8 ||
11910 | hfinfo->type == FT_INT16 ||
11911 | hfinfo->type == FT_INT24 ||
11912 | hfinfo->type == FT_INT32 ||
11913 | hfinfo->type == FT_INT40 ||
11914 | hfinfo->type == FT_INT48 ||
11915 | hfinfo->type == FT_INT56 ||
11916 | hfinfo->type == FT_INT64 ||
11917 | hfinfo->type == FT_FLOAT ||
11918 | hfinfo->type == FT_DOUBLE)) {
11919 |
11920 | if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
11921 | range = (const range_string *)hfinfo->strings;
11922 | } else if (hfinfo->display & BASE_EXT_STRING0x00000200) {
11923 | if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11924 | vals64 = VAL64_STRING_EXT_VS_P((const val64_string_ext *)hfinfo->strings)((const val64_string_ext *)hfinfo->strings)->_vs_p;
11925 | } else {
11926 | vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings)((const value_string_ext *)hfinfo->strings)->_vs_p;
11927 | }
11928 | } else if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11929 | vals64 = (const val64_string *)hfinfo->strings;
11930 | } else if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
11931 | units = (const unit_name_string *)hfinfo->strings;
11932 | } else {
11933 | vals = (const value_string *)hfinfo->strings;
11934 | }
11935 | }
11936 | else if (hfinfo->type == FT_BOOLEAN) {
11937 | tfs = (const struct true_false_string *)hfinfo->strings;
11938 | }
11939 | }
11940 |
11941 | /* Print value strings? */
11942 | if (vals) {
11943 | if (hfinfo->display & BASE_EXT_STRING0x00000200) {
11944 | if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11945 | val64_string_ext *vse_p = (val64_string_ext *)hfinfo->strings;
11946 | if (!val64_string_ext_validate(vse_p)) {
11947 | ws_warning("Invalid val64_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 11947, __func__, "Invalid val64_string_ext ptr for: %s", hfinfo ->abbrev); } } while (0);
11948 | continue;
11949 | }
11950 | try_val64_to_str_ext(0, vse_p); /* "prime" the extended val64_string */
11951 | printf("E\t%s\t%u\t%s\t%s\n",
11952 | hfinfo->abbrev,
11953 | VAL64_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
11954 | VAL64_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
11955 | val64_string_ext_match_type_str(vse_p));
11956 | } else {
11957 | value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
11958 | if (!value_string_ext_validate(vse_p)) {
11959 | ws_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 11959, __func__, "Invalid value_string_ext ptr for: %s", hfinfo ->abbrev); } } while (0);
11960 | continue;
11961 | }
11962 | try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
11963 | printf("E\t%s\t%u\t%s\t%s\n",
11964 | hfinfo->abbrev,
11965 | VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
11966 | VALUE_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
11967 | value_string_ext_match_type_str(vse_p));
11968 | }
11969 | }
11970 | vi = 0;
11971 | while (vals[vi].strptr) {
11972 | /* Print in the proper base */
11973 | if (hfinfo->type == FT_CHAR) {
11974 | if (g_ascii_isprint(vals[vi].value)((g_ascii_table[(guchar) (vals[vi].value)] & G_ASCII_PRINT ) != 0)) {
11975 | printf("V\t%s\t'%c'\t%s\n",
11976 | hfinfo->abbrev,
11977 | vals[vi].value,
11978 | vals[vi].strptr);
11979 | } else {
11980 | if (hfinfo->display == BASE_HEX) {
11981 | printf("V\t%s\t'\\x%02x'\t%s\n",
11982 | hfinfo->abbrev,
11983 | vals[vi].value,
11984 | vals[vi].strptr);
11985 | }
11986 | else {
11987 | printf("V\t%s\t'\\%03o'\t%s\n",
11988 | hfinfo->abbrev,
11989 | vals[vi].value,
11990 | vals[vi].strptr);
11991 | }
11992 | }
11993 | } else {
11994 | if (hfinfo->display == BASE_HEX) {
11995 | printf("V\t%s\t0x%x\t%s\n",
11996 | hfinfo->abbrev,
11997 | vals[vi].value,
11998 | vals[vi].strptr);
11999 | }
12000 | else {
12001 | printf("V\t%s\t%u\t%s\n",
12002 | hfinfo->abbrev,
12003 | vals[vi].value,
12004 | vals[vi].strptr);
12005 | }
12006 | }
12007 | vi++;
12008 | }
12009 | }
12010 | else if (vals64) {
12011 | vi = 0;
12012 | while (vals64[vi].strptr) {
12013 | printf("V64\t%s\t%" PRIu64"l" "u" "\t%s\n",
12014 | hfinfo->abbrev,
12015 | vals64[vi].value,
12016 | vals64[vi].strptr);
12017 | vi++;
12018 | }
12019 | }
12020 |
12021 | /* print range strings? */
12022 | else if (range) {
12023 | vi = 0;
12024 | while (range[vi].strptr) {
12025 | /* Print in the proper base */
12026 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_HEX) {
12027 | printf("R\t%s\t0x%"PRIx64"l" "x""\t0x%"PRIx64"l" "x""\t%s\n",
12028 | hfinfo->abbrev,
12029 | range[vi].value_min,
12030 | range[vi].value_max,
12031 | range[vi].strptr);
12032 | }
12033 | else {
12034 | printf("R\t%s\t%"PRIu64"l" "u""\t%"PRIu64"l" "u""\t%s\n",
12035 | hfinfo->abbrev,
12036 | range[vi].value_min,
12037 | range[vi].value_max,
12038 | range[vi].strptr);
12039 | }
12040 | vi++;
12041 | }
12042 | }
12043 |
12044 | /* Print true/false strings? */
12045 | else if (tfs) {
12046 | printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
12047 | tfs->true_string, tfs->false_string);
12048 | }
12049 | /* Print unit strings? */
12050 | else if (units) {
12051 | printf("U\t%s\t%s\t%s\n", hfinfo->abbrev,
12052 | units->singular, units->plural ? units->plural : "(no plural)");
12053 | }
12054 | }
12055 | }
12056 |
12057 | /* Prints the number of registered fields.
12058 | * Useful for determining an appropriate value for
12059 | * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
12060 | *
12061 | * Returns false if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
12062 | * the number of fields, true otherwise.
12063 | */
12064 | bool_Bool
12065 | proto_registrar_dump_fieldcount(void)
12066 | {
12067 | struct proto_registrar_stats stats = {0, 0, 0};
12068 | size_t total_count = proto_registrar_get_count(&stats);
12069 |
12070 | printf("There are %zu header fields registered, of which:\n"
12071 | "\t%zu are deregistered\n"
12072 | "\t%zu are protocols\n"
12073 | "\t%zu have the same name as another field\n\n",
12074 | total_count, stats.deregistered_count, stats.protocol_count,
12075 | stats.same_name_count);
12076 |
12077 | printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000),
12078 | (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000)) ?
12079 | "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
12080 | "\n");
12081 |
12082 | printf("The header field table consumes %u KiB of memory.\n",
12083 | (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
12084 | printf("The fields themselves consume %u KiB of memory.\n",
12085 | (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
12086 |
12087 | return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
12088 | }
12089 |
12090 | static void
12091 | elastic_add_base_mapping(json_dumper *dumper)
12092 | {
12093 | json_dumper_set_member_name(dumper, "index_patterns");
12094 | json_dumper_begin_array(dumper);
12095 | // The index names from write_json_index() in print.c
12096 | json_dumper_value_string(dumper, "packets-*");
12097 | json_dumper_end_array(dumper);
12098 |
12099 | json_dumper_set_member_name(dumper, "settings");
12100 | json_dumper_begin_object(dumper);
12101 | json_dumper_set_member_name(dumper, "index.mapping.total_fields.limit");
12102 | json_dumper_value_anyf(dumper, "%d", 1000000);
12103 | json_dumper_end_object(dumper);
12104 | }
12105 |
12106 | static char*
12107 | ws_type_to_elastic(unsigned type)
12108 | {
12109 | switch(type) {
12110 | case FT_INT8:
12111 | return "byte";
12112 | case FT_UINT8:
12113 | case FT_INT16:
12114 | return "short";
12115 | case FT_UINT16:
12116 | case FT_INT32:
12117 | case FT_UINT24:
12118 | case FT_INT24:
12119 | return "integer";
12120 | case FT_FRAMENUM:
12121 | case FT_UINT32:
12122 | case FT_UINT40:
12123 | case FT_UINT48:
12124 | case FT_UINT56:
12125 | case FT_INT40:
12126 | case FT_INT48:
12127 | case FT_INT56:
12128 | case FT_INT64:
12129 | return "long";
12130 | case FT_UINT64:
12131 | return "unsigned long"; // ElasticSearch since 7.0, OpenSearch 2.8
12132 | case FT_FLOAT:
12133 | return "float";
12134 | case FT_DOUBLE:
12135 | case FT_RELATIVE_TIME: // "scaled_float" with "scaling_factor" 1e9 superior?
12136 | return "double";
12137 | case FT_IPv6:
12138 | case FT_IPv4:
12139 | return "ip";
12140 | case FT_ABSOLUTE_TIME:
12141 | return "date_nanos"; // This is a 64 bit integer of nanoseconds, so it does have a Y2262 problem
12142 | case FT_BOOLEAN:
12143 | return "boolean";
12144 | default:
12145 | return NULL((void*)0);
12146 | }
12147 | }
12148 |
12149 | static char*
12150 | dot_to_underscore(char* str)
12151 | {
12152 | unsigned i;
12153 | for (i = 0; i < strlen(str); i++) {
12154 | if (str[i] == '.')
12155 | str[i] = '_';
12156 | }
12157 | return str;
12158 | }
12159 |
12160 | /* Dumps a mapping file for ElasticSearch
12161 | * This is the v1 (legacy) _template API.
12162 | * At some point it may need to be updated with the composable templates
12163 | * introduced in Elasticsearch 7.8 (_index_template)
12164 | */
12165 | void
12166 | proto_registrar_dump_elastic(const char* filter)
12167 | {
12168 | header_field_info *hfinfo;
12169 | header_field_info *parent_hfinfo;
12170 | unsigned i;
12171 | bool_Bool open_object = true1;
12172 | const char* prev_proto = NULL((void*)0);
12173 | char* str;
12174 | char** protos = NULL((void*)0);
12175 | char* proto;
12176 | bool_Bool found;
12177 | unsigned j;
12178 | char* type;
12179 | char* prev_item = NULL((void*)0);
12180 |
12181 | /* We have filtering protocols. Extract them. */
12182 | if (filter) {
12183 | protos = g_strsplit(filter, ",", -1);
12184 | }
12185 |
12186 | /*
12187 | * To help tracking down the json tree, objects have been appended with a comment:
12188 | * n.label -> where n is the indentation level and label the name of the object
12189 | */
12190 |
12191 | json_dumper dumper = {
12192 | .output_file = stdoutstdout,
12193 | .flags = JSON_DUMPER_FLAGS_PRETTY_PRINT(1 << 0),
12194 | };
12195 | json_dumper_begin_object(&dumper); // 1.root
12196 | elastic_add_base_mapping(&dumper);
12197 |
12198 | json_dumper_set_member_name(&dumper, "mappings");
12199 | json_dumper_begin_object(&dumper); // 2.mappings
12200 |
12201 | json_dumper_set_member_name(&dumper, "properties");
12202 | json_dumper_begin_object(&dumper); // 3.properties
12203 | json_dumper_set_member_name(&dumper, "timestamp");
12204 | json_dumper_begin_object(&dumper); // 4.timestamp
12205 | json_dumper_set_member_name(&dumper, "type");
12206 | json_dumper_value_string(&dumper, "date");
12207 | json_dumper_end_object(&dumper); // 4.timestamp
12208 |
12209 | json_dumper_set_member_name(&dumper, "layers");
12210 | json_dumper_begin_object(&dumper); // 4.layers
12211 | json_dumper_set_member_name(&dumper, "properties");
12212 | json_dumper_begin_object(&dumper); // 5.properties
12213 |
12214 | for (i = 1; i < gpa_hfinfo.len; i++) {
12215 | if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12216 | continue; /* This is a deregistered protocol or header field */
12217 |
12218 | 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", 12218 , __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", 12218 , "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", 12218, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[i];;
12219 |
12220 | /*
12221 | * Skip the pseudo-field for "proto_tree_add_text()" since
12222 | * we don't want it in the list of filterable protocols.
12223 | */
12224 | if (hfinfo->id == hf_text_only)
12225 | continue;
12226 |
12227 | if (!proto_registrar_is_protocol(i)) {
12228 | 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", 12228 , __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", 12228 , "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", 12228 , "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!" )))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];;
12229 |
12230 | /*
12231 | * Skip the field if filter protocols have been set and this one's
12232 | * parent is not listed.
12233 | */
12234 | if (protos) {
12235 | found = false0;
12236 | j = 0;
12237 | proto = protos[0];
12238 | while(proto) {
12239 | if (!g_strcmp0(proto, parent_hfinfo->abbrev)) {
12240 | found = true1;
12241 | break;
12242 | }
12243 | j++;
12244 | proto = protos[j];
12245 | }
12246 | if (!found)
12247 | continue;
12248 | }
12249 |
12250 | if (prev_proto && g_strcmp0(parent_hfinfo->abbrev, prev_proto)) {
12251 | json_dumper_end_object(&dumper); // 7.properties
12252 | json_dumper_end_object(&dumper); // 8.parent_hfinfo->abbrev
12253 | open_object = true1;
12254 | }
12255 |
12256 | prev_proto = parent_hfinfo->abbrev;
12257 |
12258 | if (open_object) {
12259 | json_dumper_set_member_name(&dumper, parent_hfinfo->abbrev);
12260 | json_dumper_begin_object(&dumper); // 6.parent_hfinfo->abbrev
12261 | json_dumper_set_member_name(&dumper, "properties");
12262 | json_dumper_begin_object(&dumper); // 7.properties
12263 | open_object = false0;
12264 | }
12265 | /* Skip the fields that would map into string. This is the default in elasticsearch. */
12266 | type = ws_type_to_elastic(hfinfo->type);
12267 | /* when type is NULL, we have the default mapping: string */
12268 | if (type) {
12269 | str = ws_strdup_printf("%s_%s", prev_proto, hfinfo->abbrev)wmem_strdup_printf(((void*)0), "%s_%s", prev_proto, hfinfo-> abbrev);
12270 | dot_to_underscore(str);
12271 | if (g_strcmp0(prev_item, str)) {
12272 | json_dumper_set_member_name(&dumper, str);
12273 | json_dumper_begin_object(&dumper); // 8.hfinfo->abbrev
12274 | json_dumper_set_member_name(&dumper, "type");
12275 | json_dumper_value_string(&dumper, type);
12276 | json_dumper_end_object(&dumper); // 8.hfinfo->abbrev
12277 | }
12278 | g_free(prev_item);
12279 | prev_item = str;
12280 | }
12281 | }
12282 | }
12283 | g_free(prev_item);
12284 |
12285 | if (prev_proto) {
12286 | json_dumper_end_object(&dumper); // 7.properties
12287 | json_dumper_end_object(&dumper); // 6.parent_hfinfo->abbrev
12288 | }
12289 |
12290 | json_dumper_end_object(&dumper); // 5.properties
12291 | json_dumper_end_object(&dumper); // 4.layers
12292 | json_dumper_end_object(&dumper); // 3.properties
12293 | json_dumper_end_object(&dumper); // 2.mappings
12294 | json_dumper_end_object(&dumper); // 1.root
12295 | bool_Bool ret = json_dumper_finish(&dumper);
12296 | DISSECTOR_ASSERT(ret)((void) ((ret) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 12296, "ret"))));
12297 |
12298 | g_strfreev(protos);
12299 | }
12300 |
12301 | /* Dumps the contents of the registration database to stdout. An independent
12302 | * program can take this output and format it into nice tables or HTML or
12303 | * whatever.
12304 | *
12305 | * There is one record per line. Each record is either a protocol or a header
12306 | * field, differentiated by the first field. The fields are tab-delimited.
12307 | *
12308 | * Protocols
12309 | * ---------
12310 | * Field 1 = 'P'
12311 | * Field 2 = descriptive protocol name
12312 | * Field 3 = protocol abbreviation
12313 | *
12314 | * Header Fields
12315 | * -------------
12316 | * Field 1 = 'F'
12317 | * Field 2 = descriptive field name
12318 | * Field 3 = field abbreviation
12319 | * Field 4 = type ( textual representation of the ftenum type )
12320 | * Field 5 = parent protocol abbreviation
12321 | * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
12322 | * Field 7 = bitmask: format: hex: 0x....
12323 | * Field 8 = blurb describing field
12324 | */
12325 | void
12326 | proto_registrar_dump_fields(void)
12327 | {
12328 | header_field_info *hfinfo, *parent_hfinfo;
12329 | int i, len;
12330 | const char *enum_name;
12331 | const char *base_name;
12332 | const char *blurb;
12333 | char width[5];
12334 |
12335 | len = gpa_hfinfo.len;
12336 | for (i = 1; i < len ; i++) {
12337 | if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12338 | continue; /* This is a deregistered protocol or header field */
12339 |
12340 | 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", 12340 , __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", 12340 , "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", 12340, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[i];;
12341 |
12342 | /*
12343 | * Skip the pseudo-field for "proto_tree_add_text()" since
12344 | * we don't want it in the list of filterable fields.
12345 | */
12346 | if (hfinfo->id == hf_text_only)
12347 | continue;
12348 |
12349 | /* format for protocols */
12350 | if (proto_registrar_is_protocol(i)) {
12351 | printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
12352 | }
12353 | /* format for header fields */
12354 | else {
12355 | /*
12356 | * If this field isn't at the head of the list of
12357 | * fields with this name, skip this field - all
12358 | * fields with the same name are really just versions
12359 | * of the same field stored in different bits, and
12360 | * should have the same type/radix/value list, and
12361 | * just differ in their bit masks. (If a field isn't
12362 | * a bitfield, but can be, say, 1 or 2 bytes long,
12363 | * it can just be made FT_UINT16, meaning the
12364 | * *maximum* length is 2 bytes, and be used
12365 | * for all lengths.)
12366 | */
12367 | if (hfinfo->same_name_prev_id != -1)
12368 | continue;
12369 |
12370 | 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", 12370 , __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", 12370 , "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", 12370 , "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!" )))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];;
12371 |
12372 | enum_name = ftype_name(hfinfo->type);
12373 | base_name = "";
12374 |
12375 | if (hfinfo->type == FT_CHAR ||
12376 | hfinfo->type == FT_UINT8 ||
12377 | hfinfo->type == FT_UINT16 ||
12378 | hfinfo->type == FT_UINT24 ||
12379 | hfinfo->type == FT_UINT32 ||
12380 | hfinfo->type == FT_UINT40 ||
12381 | hfinfo->type == FT_UINT48 ||
12382 | hfinfo->type == FT_UINT56 ||
12383 | hfinfo->type == FT_UINT64 ||
12384 | hfinfo->type == FT_INT8 ||
12385 | hfinfo->type == FT_INT16 ||
12386 | hfinfo->type == FT_INT24 ||
12387 | hfinfo->type == FT_INT32 ||
12388 | hfinfo->type == FT_INT40 ||
12389 | hfinfo->type == FT_INT48 ||
12390 | hfinfo->type == FT_INT56 ||
12391 | hfinfo->type == FT_INT64) {
12392 |
12393 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
12394 | case BASE_NONE:
12395 | case BASE_DEC:
12396 | case BASE_HEX:
12397 | case BASE_OCT:
12398 | case BASE_DEC_HEX:
12399 | case BASE_HEX_DEC:
12400 | case BASE_CUSTOM:
12401 | case BASE_PT_UDP:
12402 | case BASE_PT_TCP:
12403 | case BASE_PT_DCCP:
12404 | case BASE_PT_SCTP:
12405 | case BASE_OUI:
12406 | base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF), hf_display, "????");
12407 | break;
12408 | default:
12409 | base_name = "????";
12410 | break;
12411 | }
12412 | } else if (hfinfo->type == FT_BOOLEAN) {
12413 | /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
12414 | snprintf(width, sizeof(width), "%d", hfinfo->display);
12415 | base_name = width;
12416 | }
12417 |
12418 | blurb = hfinfo->blurb;
12419 | if (blurb == NULL((void*)0))
12420 | blurb = "";
12421 | else if (strlen(blurb) == 0)
12422 | blurb = "\"\"";
12423 |
12424 | printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" PRIx64"l" "x" "\t%s\n",
12425 | hfinfo->name, hfinfo->abbrev, enum_name,
12426 | parent_hfinfo->abbrev, base_name,
12427 | hfinfo->bitmask, blurb);
12428 | }
12429 | }
12430 | }
12431 |
12432 | /* Dumps all abbreviated field and protocol completions of the given string to
12433 | * stdout. An independent program may use this for command-line tab completion
12434 | * of fields.
12435 | */
12436 | bool_Bool
12437 | proto_registrar_dump_field_completions(const char *prefix)
12438 | {
12439 | header_field_info *hfinfo;
12440 | int i, len;
12441 | size_t prefix_len;
12442 | bool_Bool matched = false0;
12443 |
12444 | prefix_len = strlen(prefix);
12445 | len = gpa_hfinfo.len;
12446 | for (i = 1; i < len ; i++) {
12447 | if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12448 | continue; /* This is a deregistered protocol or header field */
12449 |
12450 | 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", 12450 , __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", 12450 , "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", 12450, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[i];;
12451 |
12452 | /*
12453 | * Skip the pseudo-field for "proto_tree_add_text()" since
12454 | * we don't want it in the list of filterable fields.
12455 | */
12456 | if (hfinfo->id == hf_text_only)
12457 | continue;
12458 |
12459 | /* format for protocols */
12460 | if (proto_registrar_is_protocol(i)) {
12461 | if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12462 | matched = true1;
12463 | printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12464 | }
12465 | }
12466 | /* format for header fields */
12467 | else {
12468 | /*
12469 | * If this field isn't at the head of the list of
12470 | * fields with this name, skip this field - all
12471 | * fields with the same name are really just versions
12472 | * of the same field stored in different bits, and
12473 | * should have the same type/radix/value list, and
12474 | * just differ in their bit masks. (If a field isn't
12475 | * a bitfield, but can be, say, 1 or 2 bytes long,
12476 | * it can just be made FT_UINT16, meaning the
12477 | * *maximum* length is 2 bytes, and be used
12478 | * for all lengths.)
12479 | */
12480 | if (hfinfo->same_name_prev_id != -1)
12481 | continue;
12482 |
12483 | if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12484 | matched = true1;
12485 | printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12486 | }
12487 | }
12488 | }
12489 | return matched;
12490 | }
12491 |
12492 | /* Dumps field types and descriptive names to stdout. An independent
12493 | * program can take this output and format it into nice tables or HTML or
12494 | * whatever.
12495 | *
12496 | * There is one record per line. The fields are tab-delimited.
12497 | *
12498 | * Field 1 = field type name, e.g. FT_UINT8
12499 | * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
12500 | */
12501 | void
12502 | proto_registrar_dump_ftypes(void)
12503 | {
12504 | int fte;
12505 |
12506 | for (fte = 0; fte < FT_NUM_TYPES; fte++) {
12507 | printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
12508 | }
12509 | }
12510 |
12511 | /* This function indicates whether it's possible to construct a
12512 | * "match selected" display filter string for the specified field,
12513 | * returns an indication of whether it's possible, and, if it's
12514 | * possible and "filter" is non-null, constructs the filter and
12515 | * sets "*filter" to point to it.
12516 | * You do not need to [g_]free() this string since it will be automatically
12517 | * freed once the next packet is dissected.
12518 | */
12519 | static bool_Bool
12520 | construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt,
12521 | char **filter)
12522 | {
12523 | const header_field_info *hfinfo;
12524 | int start, length, length_remaining;
12525 |
12526 | if (!finfo)
12527 | return false0;
12528 |
12529 | hfinfo = finfo->hfinfo;
12530 | DISSECTOR_ASSERT(hfinfo)((void) ((hfinfo) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 12530, "hfinfo"))));
12531 |
12532 | /* If we have BASE_NONE and strings (a non-NULL FIELDCONVERT),
12533 | * then "the numeric value ... is not used when preparing
12534 | * filters for the field in question." If it's any other
12535 | * base, we'll generate the filter normally (which will
12536 | * be numeric, even though the human-readable string does
12537 | * work for filtering.)
12538 | *
12539 | * XXX - It might be nice to use fvalue_to_string_repr() in
12540 | * "proto_item_fill_label()" as well, although, there, you'd
12541 | * have to deal with the base *and* with resolved values for
12542 | * addresses.
12543 | *
12544 | * Perhaps in addition to taking the repr type (DISPLAY
12545 | * or DFILTER) and the display (base), fvalue_to_string_repr()
12546 | * should have the the "strings" values in the header_field_info
12547 | * structure for the field as a parameter, so it can have
12548 | * if the field is Boolean or an enumerated integer type,
12549 | * the tables used to generate human-readable values.
12550 | */
12551 | if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_NONE) {
12552 | const char *str = NULL((void*)0);
12553 |
12554 | switch (hfinfo->type) {
12555 |
12556 | case FT_INT8:
12557 | case FT_INT16:
12558 | case FT_INT24:
12559 | case FT_INT32:
12560 | str = hf_try_val_to_str(fvalue_get_sinteger(finfo->value), hfinfo);
12561 | break;
12562 |
12563 | case FT_CHAR:
12564 | case FT_UINT8:
12565 | case FT_UINT16:
12566 | case FT_UINT24:
12567 | case FT_UINT32:
12568 | str = hf_try_val_to_str(fvalue_get_uinteger(finfo->value), hfinfo);
12569 | break;
12570 |
12571 | default:
12572 | break;
12573 | }
12574 |
12575 | if (str != NULL((void*)0) && filter != NULL((void*)0)) {
12576 | *filter = wmem_strdup_printf(NULL((void*)0), "%s == \"%s\"", hfinfo->abbrev, str);
12577 | return true1;
12578 | }
12579 | }
12580 |
12581 | switch (hfinfo->type) {
12582 |
12583 | case FT_PROTOCOL:
12584 | if (filter != NULL((void*)0))
12585 | *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12586 | break;
12587 |
12588 | case FT_NONE:
12589 | /*
12590 | * If the length is 0, just match the name of the
12591 | * field.
12592 | *
12593 | * (Also check for negative values, just in case,
12594 | * as we'll cast it to an unsigned value later.)
12595 | */
12596 | length = finfo->length;
12597 | if (length == 0) {
12598 | if (filter != NULL((void*)0))
12599 | *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12600 | break;
12601 | }
12602 | if (length < 0)
12603 | return false0;
12604 |
12605 | /*
12606 | * This doesn't have a value, so we'd match
12607 | * on the raw bytes at this address.
12608 | *
12609 | * Should we be allowed to access to the raw bytes?
12610 | * If "edt" is NULL, the answer is "no".
12611 | */
12612 | if (edt == NULL((void*)0))
12613 | return false0;
12614 |
12615 | /*
12616 | * Is this field part of the raw frame tvbuff?
12617 | * If not, we can't use "frame[N:M]" to match
12618 | * it.
12619 | *
12620 | * XXX - should this be frame-relative, or
12621 | * protocol-relative?
12622 | *
12623 | * XXX - does this fallback for non-registered
12624 | * fields even make sense?
12625 | */
12626 | if (finfo->ds_tvb != edt->tvb)
12627 | return false0; /* you lose */
12628 |
12629 | /*
12630 | * Don't go past the end of that tvbuff.
12631 | */
12632 | length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
12633 | if (length > length_remaining)
12634 | length = length_remaining;
12635 | if (length <= 0)
12636 | return false0;
12637 |
12638 | if (filter != NULL((void*)0)) {
12639 | start = finfo->start;
12640 | char *str = bytes_to_dfilter_repr(NULL((void*)0), tvb_get_ptr(finfo->ds_tvb, start, length), length);
12641 | *filter = wmem_strdup_printf(NULL((void*)0), "frame[%d:%d] == %s", finfo->start, length, str);
12642 | wmem_free(NULL((void*)0), str);
12643 | }
12644 | break;
12645 |
12646 | /* By default, use the fvalue's "to_string_repr" method. */
12647 | default:
12648 | if (filter != NULL((void*)0)) {
12649 | char *str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
12650 | *filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", hfinfo->abbrev, str);
12651 | wmem_free(NULL((void*)0), str);
12652 | }
12653 | break;
12654 | }
12655 |
12656 | return true1;
12657 | }
12658 |
12659 | /*
12660 | * Returns true if we can do a "match selected" on the field, false
12661 | * otherwise.
12662 | */
12663 | bool_Bool
12664 | proto_can_match_selected(const field_info *finfo, epan_dissect_t *edt)
12665 | {
12666 | return construct_match_selected_string(finfo, edt, NULL((void*)0));
12667 | }
12668 |
12669 | /* This function attempts to construct a "match selected" display filter
12670 | * string for the specified field; if it can do so, it returns a pointer
12671 | * to the string, otherwise it returns NULL.
12672 | *
12673 | * The string is wmem allocated and must be freed with "wmem_free(NULL, ...)".
12674 | */
12675 | char *
12676 | proto_construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt)
12677 | {
12678 | char *filter = NULL((void*)0);
12679 |
12680 | if (!construct_match_selected_string(finfo, edt, &filter))
12681 | {
12682 | wmem_free(NULL((void*)0), filter);
12683 | return NULL((void*)0);
12684 | }
12685 | return filter;
12686 | }
12687 |
12688 | /* This function is common code for all proto_tree_add_bitmask... functions.
12689 | */
12690 |
12691 | static bool_Bool
12692 | proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
12693 | const int len, const int ett, int * const *fields,
12694 | const int flags, bool_Bool first,
12695 | bool_Bool use_parent_tree,
12696 | proto_tree* tree, uint64_t value)
12697 | {
12698 | uint64_t available_bits = UINT64_MAX(18446744073709551615UL);
12699 | uint64_t bitmask = 0;
12700 | uint64_t tmpval;
12701 | header_field_info *hf;
12702 | uint32_t integer32;
12703 | int bit_offset;
12704 | int no_of_bits;
12705 |
12706 | if (!*fields)
12707 | 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" );
12708 |
12709 | if (len < 0 || len > 8)
12710 | REPORT_DISSECTOR_BUG("Invalid len: %d", len)proto_report_dissector_bug("Invalid len: %d", len);
12711 | /**
12712 | * packet-frame.c uses len=0 since the value is taken from the packet
12713 | * metadata, not the packet bytes. In that case, assume that all bits
12714 | * in the provided value are valid.
12715 | */
12716 | if (len > 0) {
12717 | available_bits >>= (8 - (unsigned)len)*8;
12718 | }
12719 |
12720 | if (use_parent_tree == false0)
12721 | tree = proto_item_add_subtree(item, ett);
12722 |
12723 | while (*fields) {
12724 | uint64_t present_bits;
12725 | 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", 12725, __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", 12725 , "**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", 12725, "gpa_hfinfo.hfi[**fields] != ((void*)0)" , "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[**fields];;
12726 | 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", 12726 , "hf->bitmask != 0", hf->abbrev))));
12727 |
12728 | bitmask |= hf->bitmask;
12729 |
12730 | /* Skip fields that aren't fully present */
12731 | present_bits = available_bits & hf->bitmask;
12732 | if (present_bits != hf->bitmask) {
12733 | fields++;
12734 | continue;
12735 | }
12736 |
12737 | switch (hf->type) {
12738 | case FT_CHAR:
12739 | case FT_UINT8:
12740 | case FT_UINT16:
12741 | case FT_UINT24:
12742 | case FT_UINT32:
12743 | proto_tree_add_uint(tree, **fields, tvb, offset, len, (uint32_t)value);
12744 | break;
12745 |
12746 | case FT_INT8:
12747 | case FT_INT16:
12748 | case FT_INT24:
12749 | case FT_INT32:
12750 | proto_tree_add_int(tree, **fields, tvb, offset, len, (int32_t)value);
12751 | break;
12752 |
12753 | case FT_UINT40:
12754 | case FT_UINT48:
12755 | case FT_UINT56:
12756 | case FT_UINT64:
12757 | proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
12758 | break;
12759 |
12760 | case FT_INT40:
12761 | case FT_INT48:
12762 | case FT_INT56:
12763 | case FT_INT64:
12764 | proto_tree_add_int64(tree, **fields, tvb, offset, len, (int64_t)value);
12765 | break;
12766 |
12767 | case FT_BOOLEAN:
12768 | proto_tree_add_boolean(tree, **fields, tvb, offset, len, value);
12769 | break;
12770 |
12771 | default:
12772 | 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))
12773 | 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))
12774 | 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))
12775 | 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));
12776 | break;
12777 | }
12778 | if (flags & BMT_NO_APPEND0x01) {
12779 | fields++;
12780 | continue;
12781 | }
12782 | tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
12783 |
12784 | /* XXX: README.developer and the comments have always defined
12785 | * BMT_NO_INT as "only boolean flags are added to the title /
12786 | * don't add non-boolean (integral) fields", but the
12787 | * implementation has always added BASE_CUSTOM and fields with
12788 | * value_strings, though not fields with unit_strings.
12789 | * Possibly this is because some dissectors use a FT_UINT8
12790 | * with a value_string for fields that should be a FT_BOOLEAN.
12791 | */
12792 | switch (hf->type) {
12793 | case FT_CHAR:
12794 | if (hf->display == BASE_CUSTOM) {
12795 | char lbl[ITEM_LABEL_LENGTH240];
12796 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12797 |
12798 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 12798, "fmtfunc"))));
12799 | fmtfunc(lbl, (uint32_t) tmpval);
12800 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12801 | hf->name, lbl);
12802 | first = false0;
12803 | }
12804 | else if (hf->strings) {
12805 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12806 | hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12807 | first = false0;
12808 | }
12809 | else if (!(flags & BMT_NO_INT0x02)) {
12810 | char buf[32];
12811 | const char *out;
12812 |
12813 | if (!first) {
12814 | proto_item_append_text(item, ", ");
12815 | }
12816 |
12817 | out = hfinfo_char_value_format(hf, buf, (uint32_t) tmpval);
12818 | proto_item_append_text(item, "%s: %s", hf->name, out);
12819 | first = false0;
12820 | }
12821 |
12822 | break;
12823 |
12824 | case FT_UINT8:
12825 | case FT_UINT16:
12826 | case FT_UINT24:
12827 | case FT_UINT32:
12828 | if (hf->display == BASE_CUSTOM) {
12829 | char lbl[ITEM_LABEL_LENGTH240];
12830 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12831 |
12832 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 12832, "fmtfunc"))));
12833 | fmtfunc(lbl, (uint32_t) tmpval);
12834 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12835 | hf->name, lbl);
12836 | first = false0;
12837 | }
12838 | else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12839 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12840 | hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12841 | first = false0;
12842 | }
12843 | else if (!(flags & BMT_NO_INT0x02)) {
12844 | char buf[NUMBER_LABEL_LENGTH80];
12845 | const char *out = NULL((void*)0);
12846 |
12847 | if (!first) {
12848 | proto_item_append_text(item, ", ");
12849 | }
12850 |
12851 | if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12852 | out = hf_try_val_to_str((uint32_t) tmpval, hf);
12853 | }
12854 | if (out == NULL((void*)0)) {
12855 | out = hfinfo_number_value_format(hf, buf, (uint32_t) tmpval);
12856 | }
12857 | proto_item_append_text(item, "%s: %s", hf->name, out);
12858 | if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12859 | proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12860 | }
12861 | first = false0;
12862 | }
12863 |
12864 | break;
12865 |
12866 | case FT_INT8:
12867 | case FT_INT16:
12868 | case FT_INT24:
12869 | case FT_INT32:
12870 | integer32 = (uint32_t) tmpval;
12871 | if (hf->bitmask) {
12872 | no_of_bits = ws_count_ones(hf->bitmask);
12873 | integer32 = ws_sign_ext32(integer32, no_of_bits);
12874 | }
12875 | if (hf->display == BASE_CUSTOM) {
12876 | char lbl[ITEM_LABEL_LENGTH240];
12877 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12878 |
12879 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 12879, "fmtfunc"))));
12880 | fmtfunc(lbl, (int32_t) integer32);
12881 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12882 | hf->name, lbl);
12883 | first = false0;
12884 | }
12885 | else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12886 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12887 | hf->name, hf_try_val_to_str_const((int32_t) integer32, hf, "Unknown"));
12888 | first = false0;
12889 | }
12890 | else if (!(flags & BMT_NO_INT0x02)) {
12891 | char buf[NUMBER_LABEL_LENGTH80];
12892 | const char *out = NULL((void*)0);
12893 |
12894 | if (!first) {
12895 | proto_item_append_text(item, ", ");
12896 | }
12897 |
12898 | if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12899 | out = hf_try_val_to_str((int32_t) integer32, hf);
12900 | }
12901 | if (out == NULL((void*)0)) {
12902 | out = hfinfo_number_value_format(hf, buf, (int32_t) integer32);
12903 | }
12904 | proto_item_append_text(item, "%s: %s", hf->name, out);
12905 | if (hf->display & BASE_UNIT_STRING0x00001000) {
12906 | proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12907 | }
12908 | first = false0;
12909 | }
12910 |
12911 | break;
12912 |
12913 | case FT_UINT40:
12914 | case FT_UINT48:
12915 | case FT_UINT56:
12916 | case FT_UINT64:
12917 | if (hf->display == BASE_CUSTOM) {
12918 | char lbl[ITEM_LABEL_LENGTH240];
12919 | const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
12920 |
12921 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 12921, "fmtfunc"))));
12922 | fmtfunc(lbl, tmpval);
12923 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12924 | hf->name, lbl);
12925 | first = false0;
12926 | }
12927 | else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12928 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12929 | hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
12930 | first = false0;
12931 | }
12932 | else if (!(flags & BMT_NO_INT0x02)) {
12933 | char buf[NUMBER_LABEL_LENGTH80];
12934 | const char *out = NULL((void*)0);
12935 |
12936 | if (!first) {
12937 | proto_item_append_text(item, ", ");
12938 | }
12939 |
12940 | if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12941 | out = hf_try_val64_to_str(tmpval, hf);
12942 | }
12943 | if (out == NULL((void*)0)) {
12944 | out = hfinfo_number_value_format64(hf, buf, tmpval);
12945 | }
12946 | proto_item_append_text(item, "%s: %s", hf->name, out);
12947 | if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12948 | proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
12949 | }
12950 | first = false0;
12951 | }
12952 |
12953 | break;
12954 |
12955 | case FT_INT40:
12956 | case FT_INT48:
12957 | case FT_INT56:
12958 | case FT_INT64:
12959 | if (hf->bitmask) {
12960 | no_of_bits = ws_count_ones(hf->bitmask);
12961 | tmpval = ws_sign_ext64(tmpval, no_of_bits);
12962 | }
12963 | if (hf->display == BASE_CUSTOM) {
12964 | char lbl[ITEM_LABEL_LENGTH240];
12965 | const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
12966 |
12967 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 12967, "fmtfunc"))));
12968 | fmtfunc(lbl, (int64_t) tmpval);
12969 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12970 | hf->name, lbl);
12971 | first = false0;
12972 | }
12973 | else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12974 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12975 | hf->name, hf_try_val64_to_str_const((int64_t) tmpval, hf, "Unknown"));
12976 | first = false0;
12977 | }
12978 | else if (!(flags & BMT_NO_INT0x02)) {
12979 | char buf[NUMBER_LABEL_LENGTH80];
12980 | const char *out = NULL((void*)0);
12981 |
12982 | if (!first) {
12983 | proto_item_append_text(item, ", ");
12984 | }
12985 |
12986 | if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12987 | out = hf_try_val64_to_str((int64_t) tmpval, hf);
12988 | }
12989 | if (out == NULL((void*)0)) {
12990 | out = hfinfo_number_value_format64(hf, buf, (int64_t) tmpval);
12991 | }
12992 | proto_item_append_text(item, "%s: %s", hf->name, out);
12993 | if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12994 | proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
12995 | }
12996 | first = false0;
12997 | }
12998 |
12999 | break;
13000 |
13001 | case FT_BOOLEAN:
13002 | if (hf->strings && !(flags & BMT_NO_TFS0x08)) {
13003 | /* If we have true/false strings, emit full - otherwise messages
13004 | might look weird */
13005 | const struct true_false_string *tfs =
13006 | (const struct true_false_string *)hf->strings;
13007 |
13008 | if (tmpval) {
13009 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13010 | hf->name, tfs->true_string);
13011 | first = false0;
13012 | } else if (!(flags & BMT_NO_FALSE0x04)) {
13013 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13014 | hf->name, tfs->false_string);
13015 | first = false0;
13016 | }
13017 | } else if (hf->bitmask & value) {
13018 | /* If the flag is set, show the name */
13019 | proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
13020 | first = false0;
13021 | }
13022 | break;
13023 | default:
13024 | 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))
13025 | 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))
13026 | 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))
13027 | 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));
13028 | break;
13029 | }
13030 |
13031 | fields++;
13032 | }
13033 |
13034 | /* XXX: We don't pass the hfi into this function. Perhaps we should,
13035 | * but then again most dissectors don't set the bitmask field for
13036 | * the higher level bitmask hfi, so calculate the bitmask from the
13037 | * fields present. */
13038 | if (item) {
13039 | bit_offset = len*8 - 1 - ws_ilog2(bitmask);
13040 | no_of_bits = ws_ilog2(bitmask) - ws_ctz(bitmask) + 1;
13041 | 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);
13042 | 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);
13043 | }
13044 | return first;
13045 | }
13046 |
13047 | /* This function will dissect a sequence of bytes that describe a
13048 | * bitmask and supply the value of that sequence through a pointer.
13049 | * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13050 | * to be dissected.
13051 | * This field will form an expansion under which the individual fields of the
13052 | * bitmask is dissected and displayed.
13053 | * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13054 | *
13055 | * fields is an array of pointers to int that lists all the fields of the
13056 | * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13057 | * or another integer of the same type/size as hf_hdr with a mask specified.
13058 | * This array is terminated by a NULL entry.
13059 | *
13060 | * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13061 | * FT_integer fields that have a value_string attached will have the
13062 | * matched string displayed on the expansion line.
13063 | */
13064 | proto_item *
13065 | proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
13066 | const unsigned offset, const int hf_hdr,
13067 | const int ett, int * const *fields,
13068 | const unsigned encoding, uint64_t *retval)
13069 | {
13070 | 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);
13071 | }
13072 |
13073 | /* This function will dissect a sequence of bytes that describe a
13074 | * bitmask.
13075 | * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13076 | * to be dissected.
13077 | * This field will form an expansion under which the individual fields of the
13078 | * bitmask is dissected and displayed.
13079 | * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13080 | *
13081 | * fields is an array of pointers to int that lists all the fields of the
13082 | * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13083 | * or another integer of the same type/size as hf_hdr with a mask specified.
13084 | * This array is terminated by a NULL entry.
13085 | *
13086 | * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13087 | * FT_integer fields that have a value_string attached will have the
13088 | * matched string displayed on the expansion line.
13089 | */
13090 | proto_item *
13091 | proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
13092 | const unsigned offset, const int hf_hdr,
13093 | const int ett, int * const *fields,
13094 | const unsigned encoding)
13095 | {
13096 | return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT0x02|BMT_NO_TFS0x08);
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_ret_uint64(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 | uint64_t *retval)
13106 | {
13107 | proto_item *item = NULL((void*)0);
13108 | header_field_info *hf;
13109 | int len;
13110 | uint64_t value;
13111 |
13112 | 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", 13112, __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", 13112 , "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", 13112, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)" , "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];;
13113 | 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", 13113, (hf)->abbrev)));
13114 | len = ftype_wire_size(hf->type);
13115 | value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13116 |
13117 | if (parent_tree) {
13118 | item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13119 | proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13120 | flags, false0, false0, NULL((void*)0), value);
13121 | }
13122 |
13123 | *retval = value;
13124 | if (hf->bitmask) {
13125 | /* Mask out irrelevant portions */
13126 | *retval &= hf->bitmask;
13127 | /* Shift bits */
13128 | *retval >>= hfinfo_bitshift(hf);
13129 | }
13130 |
13131 | return item;
13132 | }
13133 |
13134 | /* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13135 | * what data is appended to the header.
13136 | */
13137 | proto_item *
13138 | proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13139 | const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags)
13140 | {
13141 | proto_item *item = NULL((void*)0);
13142 | header_field_info *hf;
13143 | int len;
13144 | uint64_t value;
13145 |
13146 | 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", 13146, __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", 13146 , "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", 13146, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)" , "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];;
13147 | 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", 13147, (hf)->abbrev)));
13148 |
13149 | if (parent_tree) {
13150 | len = ftype_wire_size(hf->type);
13151 | item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13152 | value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13153 | proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13154 | flags, false0, false0, NULL((void*)0), value);
13155 | }
13156 |
13157 | return item;
13158 | }
13159 |
13160 | /* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
13161 | can't be retrieved directly from tvb) */
13162 | proto_item *
13163 | proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13164 | const int hf_hdr, const int ett, int * const *fields, const uint64_t value)
13165 | {
13166 | return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
13167 | hf_hdr, ett, fields, value, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13168 | }
13169 |
13170 | /* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
13171 | WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern proto_item *
13172 | proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13173 | const int hf_hdr, const int ett, int * const *fields, const uint64_t value, const int flags)
13174 | {
13175 | proto_item *item = NULL((void*)0);
13176 | header_field_info *hf;
13177 | int len;
13178 |
13179 | 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", 13179, __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", 13179 , "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", 13179, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)" , "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];;
13180 | 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", 13180, (hf)->abbrev)));
13181 | /* the proto_tree_add_uint/_uint64() calls below
13182 | will fail if tvb==NULL and len!=0 */
13183 | len = tvb ? ftype_wire_size(hf->type) : 0;
13184 |
13185 | if (parent_tree) {
13186 | if (len <= 4)
13187 | item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (uint32_t)value);
13188 | else
13189 | item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
13190 |
13191 | proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13192 | flags, false0, false0, NULL((void*)0), value);
13193 | }
13194 |
13195 | return item;
13196 | }
13197 |
13198 | /* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
13199 | void
13200 | proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13201 | const int len, int * const *fields, const unsigned encoding)
13202 | {
13203 | uint64_t value;
13204 |
13205 | if (tree) {
13206 | value = get_uint64_value(tree, tvb, offset, len, encoding);
13207 | proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13208 | BMT_NO_APPEND0x01, false0, true1, tree, value);
13209 | }
13210 | }
13211 |
13212 | WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13213 | proto_tree_add_bitmask_list_ret_uint64(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13214 | const int len, int * const *fields, const unsigned encoding, uint64_t *retval)
13215 | {
13216 | uint64_t value;
13217 |
13218 | value = get_uint64_value(tree, tvb, offset, len, encoding);
13219 | if (tree) {
13220 | proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13221 | BMT_NO_APPEND0x01, false0, true1, tree, value);
13222 | }
13223 | if (retval) {
13224 | *retval = value;
13225 | }
13226 | }
13227 |
13228 | WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13229 | proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13230 | const int len, int * const *fields, const uint64_t value)
13231 | {
13232 | if (tree) {
13233 | proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13234 | BMT_NO_APPEND0x01, false0, true1, tree, value);
13235 | }
13236 | }
13237 |
13238 |
13239 | /* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
13240 | * This is intended to support bitmask fields whose lengths can vary, perhaps
13241 | * as the underlying standard evolves over time.
13242 | * With this API there is the possibility of being called to display more or
13243 | * less data than the dissector was coded to support.
13244 | * In such cases, it is assumed that bitmasks are extended on the MSb end.
13245 | * Thus when presented with "too much" or "too little" data, MSbits will be
13246 | * ignored or MSfields sacrificed.
13247 | *
13248 | * Only fields for which all defined bits are available are displayed.
13249 | */
13250 | proto_item *
13251 | proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
13252 | const unsigned offset, const unsigned len, const int hf_hdr,
13253 | const int ett, int * const *fields, struct expert_field* exp,
13254 | const unsigned encoding)
13255 | {
13256 | proto_item *item = NULL((void*)0);
13257 | header_field_info *hf;
13258 | unsigned decodable_len;
13259 | unsigned decodable_offset;
13260 | uint32_t decodable_value;
13261 | uint64_t value;
13262 |
13263 | 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", 13263, __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", 13263 , "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", 13263, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)" , "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];;
13264 | 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", 13264, (hf)->abbrev)));
13265 |
13266 | decodable_offset = offset;
13267 | decodable_len = MIN(len, (unsigned) ftype_wire_size(hf->type))(((len) < ((unsigned) ftype_wire_size(hf->type))) ? (len ) : ((unsigned) ftype_wire_size(hf->type)));
13268 |
13269 | /* If we are ftype_wire_size-limited,
13270 | * make sure we decode as many LSBs as possible.
13271 | */
13272 | if (encoding == ENC_BIG_ENDIAN0x00000000) {
13273 | decodable_offset += (len - decodable_len);
13274 | }
13275 |
13276 | if (parent_tree) {
13277 | decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
13278 | decodable_len, encoding);
13279 |
13280 | /* The root item covers all the bytes even if we can't decode them all */
13281 | item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
13282 | decodable_value);
13283 | }
13284 |
13285 | if (decodable_len < len) {
13286 | /* Dissector likely requires updating for new protocol revision */
13287 | expert_add_info_format(NULL((void*)0), item, exp,
13288 | "Only least-significant %d of %d bytes decoded",
13289 | decodable_len, len);
13290 | }
13291 |
13292 | if (item) {
13293 | value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
13294 | proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
13295 | ett, fields, BMT_NO_INT0x02|BMT_NO_TFS0x08, false0, false0, NULL((void*)0), value);
13296 | }
13297 |
13298 | return item;
13299 | }
13300 |
13301 | /* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
13302 | proto_item *
13303 | proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
13304 | const unsigned offset, const unsigned len,
13305 | const char *name, const char *fallback,
13306 | const int ett, int * const *fields,
13307 | const unsigned encoding, const int flags)
13308 | {
13309 | proto_item *item = NULL((void*)0);
13310 | uint64_t value;
13311 |
13312 | if (parent_tree) {
13313 | item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
13314 | value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13315 | if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13316 | flags, true1, false0, NULL((void*)0), value) && fallback) {
13317 | /* Still at first item - append 'fallback' text if any */
13318 | proto_item_append_text(item, "%s", fallback);
13319 | }
13320 | }
13321 |
13322 | return item;
13323 | }
13324 |
13325 | proto_item *
13326 | proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13327 | const unsigned bit_offset, const int no_of_bits,
13328 | const unsigned encoding)
13329 | {
13330 | header_field_info *hfinfo;
13331 | int octet_length;
13332 | int octet_offset;
13333 |
13334 | 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", 13334, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13334 , "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13334, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
13335 |
13336 | if (no_of_bits < 0) {
13337 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13338 | }
13339 | octet_length = (no_of_bits + 7) >> 3;
13340 | octet_offset = bit_offset >> 3;
13341 | test_length(hfinfo, tvb, octet_offset, octet_length, encoding);
13342 |
13343 | /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
13344 | * but only after doing a bunch more work (which we can, in the common
13345 | * case, shortcut here).
13346 | */
13347 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13348 | 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", 13348 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13348, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13348, "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", 13348, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
13349 |
13350 | return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL((void*)0), encoding);
13351 | }
13352 |
13353 | /*
13354 | * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
13355 | * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
13356 | * Offset should be given in bits from the start of the tvb.
13357 | */
13358 |
13359 | static proto_item *
13360 | _proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13361 | const unsigned bit_offset, const int no_of_bits,
13362 | uint64_t *return_value, const unsigned encoding)
13363 | {
13364 | int offset;
13365 | unsigned length;
13366 | uint8_t tot_no_bits;
13367 | char *bf_str;
13368 | char lbl_str[ITEM_LABEL_LENGTH240];
13369 | uint64_t value = 0;
13370 | uint8_t *bytes = NULL((void*)0);
13371 | size_t bytes_length = 0;
13372 |
13373 | proto_item *pi;
13374 | header_field_info *hf_field;
13375 |
13376 | /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13377 | 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", 13377, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13377 , "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13377, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex] ;;
13378 |
13379 | if (hf_field->bitmask != 0) {
13380 | 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)
13381 | " 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)
13382 | 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);
13383 | }
13384 |
13385 | if (no_of_bits < 0) {
13386 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13387 | } else if (no_of_bits == 0) {
13388 | 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)
13389 | 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);
13390 | }
13391 |
13392 | /* Byte align offset */
13393 | offset = bit_offset>>3;
13394 |
13395 | /*
13396 | * Calculate the number of octets used to hold the bits
13397 | */
13398 | tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13399 | length = (tot_no_bits + 7) >> 3;
13400 |
13401 | if (no_of_bits < 65) {
13402 | value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13403 | } else if (hf_field->type != FT_BYTES) {
13404 | 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)
13405 | 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);
13406 | return NULL((void*)0);
13407 | }
13408 |
13409 | /* Sign extend for signed types */
13410 | switch (hf_field->type) {
13411 | case FT_INT8:
13412 | case FT_INT16:
13413 | case FT_INT24:
13414 | case FT_INT32:
13415 | case FT_INT40:
13416 | case FT_INT48:
13417 | case FT_INT56:
13418 | case FT_INT64:
13419 | value = ws_sign_ext64(value, no_of_bits);
13420 | break;
13421 |
13422 | default:
13423 | break;
13424 | }
13425 |
13426 | if (return_value) {
13427 | *return_value = value;
13428 | }
13429 |
13430 | /* Coast clear. Try and fake it */
13431 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13432 | 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", 13432 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13432, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13432, "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", 13432, __func__, "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); } } };
13433 |
13434 | bf_str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13435 |
13436 | switch (hf_field->type) {
13437 | case FT_BOOLEAN:
13438 | /* Boolean field */
13439 | return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, value,
13440 | "%s = %s: %s",
13441 | bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13442 | break;
13443 |
13444 | case FT_CHAR:
13445 | pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13446 | fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13447 | break;
13448 |
13449 | case FT_UINT8:
13450 | case FT_UINT16:
13451 | case FT_UINT24:
13452 | case FT_UINT32:
13453 | pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13454 | fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13455 | break;
13456 |
13457 | case FT_INT8:
13458 | case FT_INT16:
13459 | case FT_INT24:
13460 | case FT_INT32:
13461 | pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (int32_t)value);
13462 | fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13463 | break;
13464 |
13465 | case FT_UINT40:
13466 | case FT_UINT48:
13467 | case FT_UINT56:
13468 | case FT_UINT64:
13469 | pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
13470 | fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13471 | break;
13472 |
13473 | case FT_INT40:
13474 | case FT_INT48:
13475 | case FT_INT56:
13476 | case FT_INT64:
13477 | pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (int64_t)value);
13478 | fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13479 | break;
13480 |
13481 | case FT_BYTES:
13482 | bytes = tvb_get_bits_array(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_bits, &bytes_length, encoding);
13483 | pi = proto_tree_add_bytes_with_length(tree, hfindex, tvb, offset, length, bytes, (int) bytes_length);
13484 | proto_item_fill_label(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13485 | proto_item_set_text(pi, "%s", lbl_str);
13486 | return pi;
13487 |
13488 | /* TODO: should handle FT_UINT_BYTES ? */
13489 |
13490 | default:
13491 | 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))
13492 | 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))
13493 | 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))
13494 | 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));
13495 | return NULL((void*)0);
13496 | }
13497 |
13498 | proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13499 | return pi;
13500 | }
13501 |
13502 | proto_item *
13503 | proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13504 | const unsigned bit_offset, const crumb_spec_t *crumb_spec,
13505 | uint64_t *return_value)
13506 | {
13507 | proto_item *pi;
13508 | int no_of_bits;
13509 | int octet_offset;
13510 | unsigned mask_initial_bit_offset;
13511 | unsigned mask_greatest_bit_offset;
13512 | unsigned octet_length;
13513 | uint8_t i;
13514 | char bf_str[256];
13515 | char lbl_str[ITEM_LABEL_LENGTH240];
13516 | uint64_t value;
13517 | uint64_t composite_bitmask;
13518 | uint64_t composite_bitmap;
13519 |
13520 | header_field_info *hf_field;
13521 |
13522 | /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13523 | 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", 13523, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13523 , "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13523, "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 | →
13524 |
13525 | if (hf_field->bitmask != 0) {
8 | ← | Assuming field 'bitmask' is equal to 0 | →
9 | ← | Taking false branch | →
13526 | 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)
13527 | " 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)
13528 | 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);
13529 | }
13530 |
13531 | mask_initial_bit_offset = bit_offset % 8;
13532 |
13533 | no_of_bits = 0;
13534 | value = 0;
13535 | i = 0;
13536 | mask_greatest_bit_offset = 0;
13537 | composite_bitmask = 0;
13538 | composite_bitmap = 0;
13539 |
13540 | 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 | →
13541 | uint64_t crumb_mask, crumb_value;
13542 | uint8_t crumb_end_bit_offset;
13543 |
13544 | crumb_value = tvb_get_bits64(tvb,
13545 | bit_offset + crumb_spec[i].crumb_bit_offset,
13546 | crumb_spec[i].crumb_bit_length,
13547 | ENC_BIG_ENDIAN0x00000000);
13548 | value += crumb_value;
13549 | no_of_bits += crumb_spec[i].crumb_bit_length;
13550 | 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", 13550 , "no_of_bits <= 64", "a value larger than 64 bits cannot be represented" ))));
12 | ← | Assuming 'no_of_bits' is <= 64 | →
13 | ← | '?' condition is true | →
13551 |
13552 | /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
13553 | octet containing the initial offset.
13554 | If the mask is beyond 32 bits, then give up on bit map display.
13555 | This could be improved in future, probably showing a table
13556 | of 32 or 64 bits per row */
13557 | if (mask_greatest_bit_offset
13.1 | 'mask_greatest_bit_offset' is < 32
< 32) {
14 | ← | Taking true branch | →
13558 | crumb_end_bit_offset = mask_initial_bit_offset
13559 | + crumb_spec[i].crumb_bit_offset
13560 | + crumb_spec[i].crumb_bit_length;
13561 | 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' | →
13562 |
13563 | if (crumb_end_bit_offset > mask_greatest_bit_offset) {
17 | ← | Assuming 'crumb_end_bit_offset' is <= 'mask_greatest_bit_offset' | →
18 | ← | Taking false branch | →
13564 | mask_greatest_bit_offset = crumb_end_bit_offset;
13565 | }
13566 | /* Currently the bitmap of the crumbs are only shown if
13567 | * smaller than 32 bits. Do not bother calculating the
13568 | * mask if it is larger than that. */
13569 | if (crumb_end_bit_offset
18.1 | 'crumb_end_bit_offset' is <= 32
<= 32) {
19 | ← | Taking true branch | →
13570 | 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'
13571 | composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
13572 | }
13573 | }
13574 | /* Shift left for the next segment */
13575 | value <<= crumb_spec[++i].crumb_bit_length;
13576 | }
13577 |
13578 | /* Sign extend for signed types */
13579 | switch (hf_field->type) {
13580 | case FT_INT8:
13581 | case FT_INT16:
13582 | case FT_INT24:
13583 | case FT_INT32:
13584 | case FT_INT40:
13585 | case FT_INT48:
13586 | case FT_INT56:
13587 | case FT_INT64:
13588 | value = ws_sign_ext64(value, no_of_bits);
13589 | break;
13590 | default:
13591 | break;
13592 | }
13593 |
13594 | if (return_value) {
13595 | *return_value = value;
13596 | }
13597 |
13598 | /* Coast clear. Try and fake it */
13599 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13600 | 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", 13600 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13600, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13600, "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", 13600, __func__, "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); } } };
13601 |
13602 | /* initialise the format string */
13603 | bf_str[0] = '\0';
13604 |
13605 | octet_offset = bit_offset >> 3;
13606 |
13607 | /* Round up mask length to nearest octet */
13608 | octet_length = ((mask_greatest_bit_offset + 7) >> 3);
13609 | mask_greatest_bit_offset = octet_length << 3;
13610 |
13611 | /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
13612 | It would be a useful enhancement to eliminate this restriction. */
13613 | if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
13614 | other_decode_bitfield_value(bf_str,
13615 | (uint32_t)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
13616 | (uint32_t)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
13617 | mask_greatest_bit_offset);
13618 | } else {
13619 | /* If the bitmask is too large, try to describe its contents. */
13620 | snprintf(bf_str, sizeof(bf_str), "%d bits", no_of_bits);
13621 | }
13622 |
13623 | switch (hf_field->type) {
13624 | case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
13625 | /* Boolean field */
13626 | return proto_tree_add_boolean_format(tree, hfindex,
13627 | tvb, octet_offset, octet_length, value,
13628 | "%s = %s: %s",
13629 | bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13630 | break;
13631 |
13632 | case FT_CHAR:
13633 | pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13634 | fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13635 | break;
13636 |
13637 | case FT_UINT8:
13638 | case FT_UINT16:
13639 | case FT_UINT24:
13640 | case FT_UINT32:
13641 | pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13642 | fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13643 | break;
13644 |
13645 | case FT_INT8:
13646 | case FT_INT16:
13647 | case FT_INT24:
13648 | case FT_INT32:
13649 | pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (int32_t)value);
13650 | fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13651 | break;
13652 |
13653 | case FT_UINT40:
13654 | case FT_UINT48:
13655 | case FT_UINT56:
13656 | case FT_UINT64:
13657 | pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
13658 | fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13659 | break;
13660 |
13661 | case FT_INT40:
13662 | case FT_INT48:
13663 | case FT_INT56:
13664 | case FT_INT64:
13665 | pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (int64_t)value);
13666 | fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13667 | break;
13668 |
13669 | default:
13670 | 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))
13671 | 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))
13672 | 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))
13673 | 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));
13674 | return NULL((void*)0);
13675 | }
13676 | proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13677 | return pi;
13678 | }
13679 |
13680 | void
13681 | proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const unsigned bit_offset,
13682 | const crumb_spec_t *crumb_spec, uint16_t crumb_index)
13683 | {
13684 | header_field_info *hfinfo;
13685 | int start = bit_offset >> 3;
13686 | int length = ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1;
13687 |
13688 | /* We have to duplicate this length check from proto_tree_add_text_internal in order to check for a null tree
13689 | * so that we can use the tree's memory scope in calculating the string */
13690 | if (length == -1) {
13691 | tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
13692 | } else {
13693 | tvb_ensure_bytes_exist(tvb, start, length);
13694 | }
13695 | if (!tree) return;
13696 |
13697 | 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", 13697, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13697 , "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13697, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
13698 | proto_tree_add_text_internal(tree, tvb, start, length,
13699 | "%s crumb %d of %s (decoded above)",
13700 | decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, crumb_spec[crumb_index].crumb_bit_length,
13701 | tvb_get_bits32(tvb,
13702 | bit_offset,
13703 | crumb_spec[crumb_index].crumb_bit_length,
13704 | ENC_BIG_ENDIAN0x00000000),
13705 | ENC_BIG_ENDIAN0x00000000),
13706 | crumb_index,
13707 | hfinfo->name);
13708 | }
13709 |
13710 | proto_item *
13711 | proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13712 | const unsigned bit_offset, const int no_of_bits,
13713 | uint64_t *return_value, const unsigned encoding)
13714 | {
13715 | proto_item *item;
13716 |
13717 | if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
13718 | bit_offset, no_of_bits,
13719 | return_value, encoding))) {
13720 | 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);
13721 | 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);
13722 | }
13723 | return item;
13724 | }
13725 |
13726 | static proto_item *
13727 | _proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13728 | tvbuff_t *tvb, const unsigned bit_offset,
13729 | const int no_of_bits, void *value_ptr,
13730 | const unsigned encoding, char *value_str)
13731 | {
13732 | int offset;
13733 | unsigned length;
13734 | uint8_t tot_no_bits;
13735 | char *str;
13736 | uint64_t value = 0;
13737 | header_field_info *hf_field;
13738 |
13739 | /* We do not have to return a value, try to fake it as soon as possible */
13740 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13741 | 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", 13741 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13741, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13741, "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", 13741, __func__, "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); } } };
13742 |
13743 | if (hf_field->bitmask != 0) {
13744 | 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)
13745 | " 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)
13746 | 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);
13747 | }
13748 |
13749 | if (no_of_bits < 0) {
13750 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13751 | } else if (no_of_bits == 0) {
13752 | 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)
13753 | 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);
13754 | }
13755 |
13756 | /* Byte align offset */
13757 | offset = bit_offset>>3;
13758 |
13759 | /*
13760 | * Calculate the number of octets used to hold the bits
13761 | */
13762 | tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13763 | length = tot_no_bits>>3;
13764 | /* If we are using part of the next octet, increase length by 1 */
13765 | if (tot_no_bits & 0x07)
13766 | length++;
13767 |
13768 | if (no_of_bits < 65) {
13769 | value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13770 | } else {
13771 | 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)
13772 | 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);
13773 | return NULL((void*)0);
13774 | }
13775 |
13776 | str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13777 |
13778 | (void) g_strlcat(str, " = ", 256+64);
13779 | (void) g_strlcat(str, hf_field->name, 256+64);
13780 |
13781 | /*
13782 | * This function does not receive an actual value but a dimensionless pointer to that value.
13783 | * For this reason, the type of the header field is examined in order to determine
13784 | * what kind of value we should read from this address.
13785 | * The caller of this function must make sure that for the specific header field type the address of
13786 | * a compatible value is provided.
13787 | */
13788 | switch (hf_field->type) {
13789 | case FT_BOOLEAN:
13790 | return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13791 | "%s: %s", str, value_str);
13792 | break;
13793 |
13794 | case FT_CHAR:
13795 | case FT_UINT8:
13796 | case FT_UINT16:
13797 | case FT_UINT24:
13798 | case FT_UINT32:
13799 | return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(uint32_t *)value_ptr,
13800 | "%s: %s", str, value_str);
13801 | break;
13802 |
13803 | case FT_UINT40:
13804 | case FT_UINT48:
13805 | case FT_UINT56:
13806 | case FT_UINT64:
13807 | return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13808 | "%s: %s", str, value_str);
13809 | break;
13810 |
13811 | case FT_INT8:
13812 | case FT_INT16:
13813 | case FT_INT24:
13814 | case FT_INT32:
13815 | return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(int32_t *)value_ptr,
13816 | "%s: %s", str, value_str);
13817 | break;
13818 |
13819 | case FT_INT40:
13820 | case FT_INT48:
13821 | case FT_INT56:
13822 | case FT_INT64:
13823 | return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(int64_t *)value_ptr,
13824 | "%s: %s", str, value_str);
13825 | break;
13826 |
13827 | case FT_FLOAT:
13828 | return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
13829 | "%s: %s", str, value_str);
13830 | break;
13831 |
13832 | default:
13833 | 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))
13834 | 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))
13835 | 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))
13836 | 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));
13837 | return NULL((void*)0);
13838 | }
13839 | }
13840 |
13841 | static proto_item *
13842 | proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13843 | tvbuff_t *tvb, const unsigned bit_offset,
13844 | const int no_of_bits, void *value_ptr,
13845 | const unsigned encoding, char *value_str)
13846 | {
13847 | proto_item *item;
13848 |
13849 | if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
13850 | tvb, bit_offset, no_of_bits,
13851 | value_ptr, encoding, value_str))) {
13852 | 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);
13853 | 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);
13854 | }
13855 | return item;
13856 | }
13857 |
13858 | #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); \
13859 | va_start(ap, format)__builtin_va_start(ap, format); \
13860 | dst = wmem_strdup_vprintf(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), format, ap); \
13861 | va_end(ap)__builtin_va_end(ap);
13862 |
13863 | proto_item *
13864 | proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
13865 | tvbuff_t *tvb, const unsigned bit_offset,
13866 | const int no_of_bits, uint32_t value,
13867 | const unsigned encoding,
13868 | const char *format, ...)
13869 | {
13870 | va_list ap;
13871 | char *dst;
13872 | header_field_info *hf_field;
13873 |
13874 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13875 |
13876 | 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", 13876 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13876, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13876, "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", 13876, __func__, "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); } } };
13877 |
13878 | switch (hf_field->type) {
13879 | case FT_UINT8:
13880 | case FT_UINT16:
13881 | case FT_UINT24:
13882 | case FT_UINT32:
13883 | break;
13884 |
13885 | default:
13886 | 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)
13887 | 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);
13888 | return NULL((void*)0);
13889 | }
13890 |
13891 | 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);;
13892 |
13893 | return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13894 | }
13895 |
13896 | proto_item *
13897 | proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
13898 | tvbuff_t *tvb, const unsigned bit_offset,
13899 | const int no_of_bits, uint64_t value,
13900 | const unsigned encoding,
13901 | const char *format, ...)
13902 | {
13903 | va_list ap;
13904 | char *dst;
13905 | header_field_info *hf_field;
13906 |
13907 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13908 |
13909 | 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", 13909 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13909, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13909, "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", 13909, __func__, "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); } } };
13910 |
13911 | switch (hf_field->type) {
13912 | case FT_UINT40:
13913 | case FT_UINT48:
13914 | case FT_UINT56:
13915 | case FT_UINT64:
13916 | break;
13917 |
13918 | default:
13919 | 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)
13920 | 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);
13921 | return NULL((void*)0);
13922 | }
13923 |
13924 | 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);;
13925 |
13926 | return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13927 | }
13928 |
13929 | proto_item *
13930 | proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
13931 | tvbuff_t *tvb, const unsigned bit_offset,
13932 | const int no_of_bits, float value,
13933 | const unsigned encoding,
13934 | const char *format, ...)
13935 | {
13936 | va_list ap;
13937 | char *dst;
13938 | header_field_info *hf_field;
13939 |
13940 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13941 |
13942 | 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", 13942 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13942, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13942, "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", 13942, __func__, "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); } } };
13943 |
13944 | 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", 13944, ((hf_field))->abbrev))));
13945 |
13946 | 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);;
13947 |
13948 | return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13949 | }
13950 |
13951 | proto_item *
13952 | proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
13953 | tvbuff_t *tvb, const unsigned bit_offset,
13954 | const int no_of_bits, int32_t value,
13955 | const unsigned encoding,
13956 | const char *format, ...)
13957 | {
13958 | va_list ap;
13959 | char *dst;
13960 | header_field_info *hf_field;
13961 |
13962 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13963 |
13964 | 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", 13964 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13964, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13964, "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", 13964, __func__, "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); } } };
13965 |
13966 | switch (hf_field->type) {
13967 | case FT_INT8:
13968 | case FT_INT16:
13969 | case FT_INT24:
13970 | case FT_INT32:
13971 | break;
13972 |
13973 | default:
13974 | 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)
13975 | 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);
13976 | return NULL((void*)0);
13977 | }
13978 |
13979 | 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);;
13980 |
13981 | return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13982 | }
13983 |
13984 | proto_item *
13985 | proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
13986 | tvbuff_t *tvb, const unsigned bit_offset,
13987 | const int no_of_bits, int64_t value,
13988 | const unsigned encoding,
13989 | const char *format, ...)
13990 | {
13991 | va_list ap;
13992 | char *dst;
13993 | header_field_info *hf_field;
13994 |
13995 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13996 |
13997 | 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", 13997 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13997, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13997, "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", 13997, __func__, "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); } } };
13998 |
13999 | switch (hf_field->type) {
14000 | case FT_INT40:
14001 | case FT_INT48:
14002 | case FT_INT56:
14003 | case FT_INT64:
14004 | break;
14005 |
14006 | default:
14007 | 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)
14008 | 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);
14009 | return NULL((void*)0);
14010 | }
14011 |
14012 | 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);;
14013 |
14014 | return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14015 | }
14016 |
14017 | proto_item *
14018 | proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
14019 | tvbuff_t *tvb, const unsigned bit_offset,
14020 | const int no_of_bits, uint64_t value,
14021 | const unsigned encoding,
14022 | const char *format, ...)
14023 | {
14024 | va_list ap;
14025 | char *dst;
14026 | header_field_info *hf_field;
14027 |
14028 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14029 |
14030 | 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", 14030 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14030, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14030, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; 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", 14030, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , 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); } } };
14031 |
14032 | 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" , 14032, ((hf_field))->abbrev))));
14033 |
14034 | 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);;
14035 |
14036 | return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14037 | }
14038 |
14039 | proto_item *
14040 | proto_tree_add_ts_23_038_7bits_packed_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14041 | const unsigned bit_offset, const int no_of_chars)
14042 | {
14043 | proto_item *pi;
14044 | header_field_info *hfinfo;
14045 | int byte_length;
14046 | int byte_offset;
14047 | char *string;
14048 |
14049 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14050 |
14051 | 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", 14051 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14051, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14051, "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", 14051, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
14052 |
14053 | 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" , 14053, ((hfinfo))->abbrev))));
14054 |
14055 | byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14056 | byte_offset = bit_offset >> 3;
14057 |
14058 | string = tvb_get_ts_23_038_7bits_string_packed(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14059 |
14060 | pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14061 | DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14061, "byte_length >= 0" ))));
14062 | proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14063 |
14064 | return pi;
14065 | }
14066 |
14067 | proto_item *
14068 | proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14069 | const unsigned bit_offset, const int no_of_chars)
14070 | {
14071 | proto_item *pi;
14072 | header_field_info *hfinfo;
14073 | int byte_length;
14074 | int byte_offset;
14075 | char *string;
14076 |
14077 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14078 |
14079 | 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", 14079 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14079, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14079, "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", 14079, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
14080 |
14081 | 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" , 14081, ((hfinfo))->abbrev))));
14082 |
14083 | byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14084 | byte_offset = bit_offset >> 3;
14085 |
14086 | string = tvb_get_ascii_7bits_string(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14087 |
14088 | pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14089 | DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14089, "byte_length >= 0" ))));
14090 | proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14091 |
14092 | return pi;
14093 | }
14094 |
14095 | const value_string proto_checksum_vals[] = {
14096 | { PROTO_CHECKSUM_E_BAD, "Bad" },
14097 | { PROTO_CHECKSUM_E_GOOD, "Good" },
14098 | { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
14099 | { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
14100 | { PROTO_CHECKSUM_E_ILLEGAL, "Illegal" },
14101 |
14102 | { 0, NULL((void*)0) }
14103 | };
14104 |
14105 | proto_item *
14106 | proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14107 | const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14108 | packet_info *pinfo, uint32_t computed_checksum, const unsigned encoding, const unsigned flags)
14109 | {
14110 | header_field_info *hfinfo;
14111 | uint32_t checksum;
14112 | uint32_t len;
14113 | proto_item* ti = NULL((void*)0);
14114 | proto_item* ti2;
14115 | bool_Bool incorrect_checksum = true1;
14116 |
14117 | 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", 14117, __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", 14117 , "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", 14117, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum ];;
14118 |
14119 | switch (hfinfo->type) {
14120 | case FT_UINT8:
14121 | len = 1;
14122 | break;
14123 | case FT_UINT16:
14124 | len = 2;
14125 | break;
14126 | case FT_UINT24:
14127 | len = 3;
14128 | break;
14129 | case FT_UINT32:
14130 | len = 4;
14131 | break;
14132 | default:
14133 | 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)
14134 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32" , hfinfo->abbrev);
14135 | }
14136 |
14137 | if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14138 | ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, len, 0, "[missing]");
14139 | proto_item_set_generated(ti);
14140 | if (hf_checksum_status != -1) {
14141 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, len, PROTO_CHECKSUM_E_NOT_PRESENT);
14142 | proto_item_set_generated(ti2);
14143 | }
14144 | return ti;
14145 | }
14146 |
14147 | if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14148 | ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, len, computed_checksum);
14149 | proto_item_set_generated(ti);
14150 | } else {
14151 | ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
14152 | if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14153 | if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14154 | if (computed_checksum == 0) {
14155 | proto_item_append_text(ti, " [correct]");
14156 | if (hf_checksum_status != -1) {
14157 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14158 | proto_item_set_generated(ti2);
14159 | }
14160 | incorrect_checksum = false0;
14161 | } else if (flags & PROTO_CHECKSUM_IN_CKSUM0x04) {
14162 | computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
14163 | /* XXX - This can't distinguish between "shouldbe"
14164 | * 0x0000 and 0xFFFF unless we know whether there
14165 | * were any nonzero bits (other than the checksum).
14166 | * Protocols should not use this path if they might
14167 | * have an all zero packet.
14168 | * Some implementations put the wrong zero; maybe
14169 | * we should have a special expert info for that?
14170 | */
14171 | }
14172 | } else {
14173 | if (checksum == computed_checksum) {
14174 | proto_item_append_text(ti, " [correct]");
14175 | if (hf_checksum_status != -1) {
14176 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14177 | proto_item_set_generated(ti2);
14178 | }
14179 | incorrect_checksum = false0;
14180 | }
14181 | }
14182 |
14183 | if (incorrect_checksum) {
14184 | if (hf_checksum_status != -1) {
14185 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14186 | proto_item_set_generated(ti2);
14187 | }
14188 | if (flags & PROTO_CHECKSUM_ZERO0x08) {
14189 | proto_item_append_text(ti, " [incorrect]");
14190 | if (bad_checksum_expert != NULL((void*)0))
14191 | expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14192 | } else {
14193 | proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
14194 | if (bad_checksum_expert != NULL((void*)0))
14195 | 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);
14196 | }
14197 | }
14198 | } else {
14199 | if (hf_checksum_status != -1) {
14200 | proto_item_append_text(ti, " [unverified]");
14201 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14202 | proto_item_set_generated(ti2);
14203 | }
14204 | }
14205 | }
14206 |
14207 | return ti;
14208 | }
14209 |
14210 | proto_item *
14211 | proto_tree_add_checksum_bytes(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14212 | const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14213 | packet_info *pinfo, const uint8_t *computed_checksum, size_t checksum_len, const unsigned flags)
14214 | {
14215 | header_field_info *hfinfo;
14216 | uint8_t *checksum = NULL((void*)0);
14217 | proto_item* ti = NULL((void*)0);
14218 | proto_item* ti2;
14219 | bool_Bool incorrect_checksum = true1;
14220 |
14221 | 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", 14221, __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", 14221 , "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", 14221, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum ];;
14222 |
14223 | if (hfinfo->type != FT_BYTES) {
14224 | 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)
14225 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BYTES" , hfinfo->abbrev);
14226 | }
14227 |
14228 | if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14229 | ti = proto_tree_add_bytes_format_value(tree, hf_checksum, tvb, offset, (int)checksum_len, 0, "[missing]");
14230 | proto_item_set_generated(ti);
14231 | if (hf_checksum_status != -1) {
14232 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, (int)checksum_len, PROTO_CHECKSUM_E_NOT_PRESENT);
14233 | proto_item_set_generated(ti2);
14234 | }
14235 | return ti;
14236 | }
14237 |
14238 | if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14239 | ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, computed_checksum);
14240 | proto_item_set_generated(ti);
14241 | } else {
14242 | 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 ))))));
14243 | tvb_memcpy(tvb, checksum, offset, checksum_len);
14244 | ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, checksum);
14245 | if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14246 | if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14247 | if (computed_checksum == 0) {
14248 | proto_item_append_text(ti, " [correct]");
14249 | if (hf_checksum_status != -1) {
14250 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14251 | proto_item_set_generated(ti2);
14252 | }
14253 | incorrect_checksum = false0;
14254 | }
14255 | } else {
14256 | if (memcmp(computed_checksum, checksum, checksum_len) == 0) {
14257 | proto_item_append_text(ti, " [correct]");
14258 | if (hf_checksum_status != -1) {
14259 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14260 | proto_item_set_generated(ti2);
14261 | }
14262 | incorrect_checksum = false0;
14263 | }
14264 | }
14265 |
14266 | if (incorrect_checksum) {
14267 | if (hf_checksum_status != -1) {
14268 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14269 | proto_item_set_generated(ti2);
14270 | }
14271 | if (flags & PROTO_CHECKSUM_ZERO0x08) {
14272 | proto_item_append_text(ti, " [incorrect]");
14273 | if (bad_checksum_expert != NULL((void*)0))
14274 | expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14275 | } else {
14276 | size_t computed_checksum_str_len = (2 * checksum_len * sizeof(char)) + 1;
14277 | 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))))));
14278 | for (size_t counter = 0; counter < checksum_len; ++counter) {
14279 | snprintf(
14280 | /* On ecah iteration inserts two characters */
14281 | (char*)&computed_checksum_str[counter << 1],
14282 | computed_checksum_str_len - (counter << 1),
14283 | "%02x",
14284 | computed_checksum[counter]);
14285 | }
14286 | proto_item_append_text(ti, " incorrect, should be 0x%s", computed_checksum_str);
14287 | if (bad_checksum_expert != NULL((void*)0))
14288 | expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s [should be 0x%s]", expert_get_summary(bad_checksum_expert), computed_checksum_str);
14289 | }
14290 | }
14291 | } else {
14292 | if (hf_checksum_status != -1) {
14293 | proto_item_append_text(ti, " [unverified]");
14294 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14295 | proto_item_set_generated(ti2);
14296 | }
14297 | }
14298 | }
14299 |
14300 | return ti;
14301 | }
14302 |
14303 | unsigned char
14304 | proto_check_field_name(const char *field_name)
14305 | {
14306 | return module_check_valid_name(field_name, false0);
14307 | }
14308 |
14309 | unsigned char
14310 | proto_check_field_name_lower(const char *field_name)
14311 | {
14312 | return module_check_valid_name(field_name, true1);
14313 | }
14314 |
14315 | bool_Bool
14316 | tree_expanded(int tree_type)
14317 | {
14318 | if (tree_type <= 0) {
14319 | return false0;
14320 | }
14321 | 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", 14321, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types" ); } while (0);
14322 | return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
14323 | }
14324 |
14325 | void
14326 | tree_expanded_set(int tree_type, bool_Bool value)
14327 | {
14328 | 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", 14328, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types" ); } while (0);
14329 |
14330 | if (value)
14331 | tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
14332 | else
14333 | tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
14334 | }
14335 |
14336 | /*
14337 | * Editor modelines - https://www.wireshark.org/tools/modelines.html
14338 | *
14339 | * Local variables:
14340 | * c-basic-offset: 8
14341 | * tab-width: 8
14342 | * indent-tabs-mode: t
14343 | * End:
14344 | *
14345 | * vi: set shiftwidth=8 tabstop=8 noexpandtab:
14346 | * :indentSize=8:tabSize=8:noTabs=false:
14347 | */