### Bug Summary

File: | builds/wireshark/wireshark/epan/proto.c
Warning: | line 13700, column 39 The result of left shift is undefined because the right operand '64' is not smaller than 64, the capacity of 'uint64_t'

### Annotated Source Code

Press '?' to see keyboard shortcuts

Show analyzer invocation
clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name proto.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -ffloat16-excess-precision=fast -fbfloat16-excess-precision=fast -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/builds/wireshark/wireshark/build -fcoverage-compilation-dir=/builds/wireshark/wireshark/build -resource-dir /usr/lib/llvm-22/lib/clang/22 -isystem /usr/include/glib-2.0 -isystem /usr/lib/x86_64-linux-gnu/glib-2.0/include -isystem /builds/wireshark/wireshark/epan -isystem /builds/wireshark/wireshark/build/epan -isystem /usr/include/mit-krb5 -isystem /usr/include/lua5.5 -isystem /usr/include/libxml2 -D CARES_NO_DEPRECATED -D G_DISABLE_DEPRECATED -D G_DISABLE_SINGLE_INCLUDES -D WS_BUILD_DLL -D WS_DEBUG -D WS_DEBUG_UTF_8 -D epan_EXPORTS -I /builds/wireshark/wireshark/build -I /builds/wireshark/wireshark -I /builds/wireshark/wireshark/include -I /builds/wireshark/wireshark/wiretap -D _GLIBCXX_ASSERTIONS -internal-isystem /usr/lib/llvm-22/lib/clang/22/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/builds/wireshark/wireshark/= -fmacro-prefix-map=/builds/wireshark/wireshark/build/= -fmacro-prefix-map=../= -Wno-format-nonliteral -std=gnu17 -ferror-limit 19 -fvisibility=hidden -fwrapv -fwrapv-pointer -fstrict-flex-arrays=3 -stack-protector 2 -fstack-clash-protection -fcf-protection=full -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fexceptions -fcolor-diagnostics -analyzer-output=html -faddrsig -fdwarf2-cfi-asm -o /builds/wireshark/wireshark/sbout/2026-06-07-100346-3530-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 | unsigned offset;
78 | };
79 |
80 | #define cVALS(x)(const value_string*)(x) (const value_string*)(x)
81 |
82 | /** See inlined comments.
83 | @param tree the tree to append this item to
84 | @param free_block a code block to call to free resources if this returns
85 | @return NULL if 'tree' is null */
86 | #define CHECK_FOR_NULL_TREE_AND_FREE(tree, free_block)if (!tree) { free_block; return ((void*)0); } \
87 | if (!tree) { \
88 | free_block; \
89 | return NULL((void*)0); \
90 | }
91 |
92 | /** See inlined comments.
93 | @param tree the tree to append this item to
94 | @return NULL if 'tree' is null */
95 | #define CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); } \
96 | CHECK_FOR_NULL_TREE_AND_FREE(tree, ((void)0))if (!tree) { ((void)0); return ((void*)0); }
97 |
98 | /** See inlined comments.
99 | @param length the length of this item
100 | @param cleanup_block a code block to call to free resources if this returns
101 | @return NULL if 'length' is lower -1 or equal 0 */
102 | #define CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length, cleanup_block)if (length < -1 || length == 0 ) { cleanup_block; return ( (void*)0); } \
103 | if (length < -1 || length == 0 ) { \
104 | cleanup_block; \
105 | return NULL((void*)0); \
106 | }
107 |
108 | /** See inlined comments.
109 | @param length the length of this item
110 | @return NULL if 'length' is lower -1 or equal 0 */
111 | #define CHECK_FOR_ZERO_OR_MINUS_LENGTH(length)if (length < -1 || length == 0 ) { ((void)0); return ((void *)0); } \
112 | CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length, ((void)0))if (length < -1 || length == 0 ) { ((void)0); return ((void *)0); }
113 |
114 | /** See inlined comments.
115 | @param tree the tree to append this item to
116 | @param hfindex field index
117 | @param hfinfo header_field
118 | @param free_block a code block to call to free resources if this returns
119 | @return the header field matching 'hfinfo' */
120 | #define TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, free_block)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned )hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug ) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 120 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 120, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 120, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items ) { free_block; if (wireshark_abort_on_too_many_items) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 120, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { free_block; return proto_tree_add_fake_node(tree, hfinfo ); } } } \
121 | /* If the tree is not visible and this item is not referenced \
122 | we don't have to do much work at all but we should still \
123 | return a node so that referenced field items below this node \
124 | (think proto_item_add_subtree()) will still have somewhere \
125 | to attach to or else filtering will not work (they would be \
126 | ignored since tree would be NULL). \
127 | DON'T try to fake a node where PTREE_FINFO(tree) is visible \
128 | because that means we can change its length or repr, and we \
129 | don't want to do so with calls intended for this faked new \
130 | item, so this item needs a new (hidden) child node. \
131 | We fake FT_PROTOCOL unless some clients have requested us \
132 | not to do so. \
133 | */ \
134 | PTREE_DATA(tree)((tree)->tree_data)->count++; \
135 | PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 135, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 135, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 135, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];; \
136 | if (PTREE_DATA(tree)((tree)->tree_data)->count > prefs.gui_max_tree_items) { \
137 | free_block; \
138 | if (wireshark_abort_on_too_many_items) \
139 | ws_error("Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)", \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 140 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items)
140 | hfinfo->abbrev, prefs.gui_max_tree_items)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 140 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); \
141 | /* Let the exception handler add items to the tree */ \
142 | PTREE_DATA(tree)((tree)->tree_data)->count = 0; \
143 | THROW_MESSAGE(DissectorError, \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data ->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items)))
144 | wmem_strdup_printf(PNODE_POOL(tree), \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data ->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items)))
145 | "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)", \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data ->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items)))
146 | hfinfo->abbrev, prefs.gui_max_tree_items))except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data ->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); \
147 | } \
148 | if (!(PTREE_DATA(tree)((tree)->tree_data)->visible)) { \
149 | if (PROTO_ITEM_IS_HIDDEN(tree)proto_item_is_hidden((tree))) { \
150 | if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) \
151 | && (hfinfo->ref_type != HF_REF_TYPE_PRINT) \
152 | && (hfinfo->type != FT_PROTOCOL || \
153 | PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) { \
154 | free_block; \
155 | /* return fake node with no field info */\
156 | return proto_tree_add_fake_node(tree, hfinfo); \
157 | } \
158 | } \
159 | }
160 |
161 | /** See inlined comments.
162 | @param tree the tree to append this item to
163 | @param hfindex field index
164 | @param hfinfo header_field
165 | @return the header field matching 'hfinfo' */
166 | #define TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned )hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug ) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 166 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 166, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 166, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items ) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 166, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } } \
167 | TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, ((void)0))((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned )hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug ) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 167 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 167, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 167, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items ) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 167, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } }
168 |
169 |
170 | /** See inlined comments.
171 | @param pi the created protocol item we're about to return */
172 | #define TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 172, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; } \
173 | ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 173, __func__, "assertion failed: %s", "pi" ); } while (0); \
174 | if (!PITEM_FINFO(pi)((pi)->finfo)) \
175 | return pi; \
176 | if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
177 | PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
178 | /* If the tree (GUI) or item isn't visible it's pointless for \
179 | * us to generate the protocol item's string representation */ \
180 | return pi; \
181 | }
182 | /* Same as above but returning void */
183 | #define TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data )->visible) && proto_item_is_hidden((pi))) { return ; } \
184 | if (!pi || !PITEM_FINFO(pi)((pi)->finfo)) \
185 | return; \
186 | if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
187 | PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
188 | /* If the tree (GUI) or item isn't visible it's pointless for \
189 | * us to generate the protocol item's string representation */ \
190 | return; \
191 | }
192 | /* Similar to above, but allows a NULL tree */
193 | #define TRY_TO_FAKE_THIS_REPR_NESTED(pi)if ((pi == ((void*)0)) || (((pi)->finfo) == ((void*)0)) || (!(((pi)->tree_data)->visible) && proto_item_is_hidden ((pi)))) { return pi; } \
194 | if ((pi == NULL((void*)0)) || (PITEM_FINFO(pi)((pi)->finfo) == NULL((void*)0)) || (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
195 | PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi)))) { \
196 | /* If the tree (GUI) or item isn't visible it's pointless for \
197 | * us to generate the protocol item's string representation */ \
198 | return pi; \
199 | }
200 |
201 | #ifdef ENABLE_CHECK_FILTER
202 | #define CHECK_HF_VALUE(type, spec, start_values) \
203 | { \
204 | const type *current; \
205 | int n, m; \
206 | current = start_values; \
207 | for (n=0; current; n++, current++) { \
208 | /* Drop out if we reached the end. */ \
209 | if ((current->value == 0) && (current->strptr == NULL((void*)0))) { \
210 | break; \
211 | } \
212 | /* Check value against all previous */ \
213 | for (m=0; m < n; m++) { \
214 | /* There are lots of duplicates with the same string, \
215 | so only report if different... */ \
216 | if ((start_values[m].value == current->value) && \
217 | (strcmp(start_values[m].strptr, current->strptr) != 0)) { \
218 | ws_error("Field '%s' (%s) has a conflicting entry in its" \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221 , __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %" spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo ->abbrev, current->value, m, start_values[m].strptr, n, current->strptr)
219 | " value_string: %" spec " is at indices %u (%s) and %u (%s)", \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221 , __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %" spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo ->abbrev, current->value, m, start_values[m].strptr, n, current->strptr)
220 | hfinfo->name, hfinfo->abbrev, \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221 , __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %" spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo ->abbrev, current->value, m, start_values[m].strptr, n, current->strptr)
221 | current->value, m, start_values[m].strptr, n, current->strptr)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221 , __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %" spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo ->abbrev, current->value, m, start_values[m].strptr, n, current->strptr); \
222 | } \
223 | } \
224 | } \
225 | }
226 | #endif
227 |
228 | /* The longest NUMBER-like field label we have is for BASE_OUI, which
229 | * can have up to 64 bytes for the manufacturer name if resolved plus
230 | * 11 bytes for the "XX:XX:XX ()" part = 75 octets.
231 | */
232 | #define NUMBER_LABEL_LENGTH80 80
233 |
234 | static const char *hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo);
235 | static const char *hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo);
236 | static const char *hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str);
237 | static const char *hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str);
238 | static int hfinfo_bitoffset(const header_field_info *hfinfo);
239 | static int hfinfo_mask_bitwidth(const header_field_info *hfinfo);
240 | static int hfinfo_container_bitwidth(const header_field_info *hfinfo);
241 |
242 | #define label_concat(dst, pos, src)ws_label_strcpy(dst, 240, pos, src, 0) \
243 | ws_label_strcpy(dst, ITEM_LABEL_LENGTH240, pos, src, 0)
244 |
245 | static void mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos);
246 | static void label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos);
247 |
248 | static void fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos);
249 | static void fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos);
250 | static void fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
251 | static void fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
252 | static void fill_label_char(const field_info *fi, char *label_str, size_t *value_pos);
253 | static void fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
254 | static void fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
255 |
256 | static size_t fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size);
257 | static void fill_label_float(const field_info *fi, char *label_str, size_t *value_pos);
258 | static size_t fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size);
259 | static void fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos);
260 |
261 | static const char *hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
262 | static const char *hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
263 | static const char *hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
264 | static const char* hfinfo_char_value_format_display(int display, char buf[7], uint32_t value);
265 | static const char *hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
266 | static const char *hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
267 | static const char *hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
268 | static const char *hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
269 | static const char *hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
270 | static const char *hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
271 | static const char *hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
272 |
273 | static void proto_cleanup_base(void);
274 |
275 | static proto_item *
276 | proto_tree_add_node(proto_tree *tree, field_info *fi);
277 |
278 | static proto_item *
279 | proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo);
280 |
281 | static void
282 | get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start, int *length,
283 | int *item_length, const unsigned encoding);
284 |
285 | static void
286 | get_hfi_length_unsigned(header_field_info * hfinfo, tvbuff_t * tvb, const unsigned start, unsigned* length,
287 | unsigned* item_length, const unsigned encoding);
288 |
289 | static int
290 | get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start,
291 | int length, unsigned item_length, const int encoding);
292 |
293 | static field_info *
294 | new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
295 | const int start, const int item_length);
296 |
297 | static proto_item *
298 | proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
299 | int start, int *length);
300 |
301 | static void
302 | proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap);
303 | static void
304 | proto_tree_set_representation(proto_item *pi, const char *format, va_list ap);
305 |
306 | static void
307 | proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length);
308 | static void
309 | proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length);
310 | static void
311 | proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, int offset, int length);
312 | static void
313 | proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value);
314 | static void
315 | proto_tree_set_time(field_info *fi, const nstime_t *value_ptr);
316 | static void
317 | proto_tree_set_string(field_info *fi, const char* value);
318 | static void
319 | proto_tree_set_ax25(field_info *fi, const uint8_t* value);
320 | static void
321 | proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, int start);
322 | static void
323 | proto_tree_set_vines(field_info *fi, const uint8_t* value);
324 | static void
325 | proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, int start);
326 | static void
327 | proto_tree_set_ether(field_info *fi, const uint8_t* value);
328 | static void
329 | proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, int start);
330 | static void
331 | proto_tree_set_ipxnet(field_info *fi, uint32_t value);
332 | static void
333 | proto_tree_set_ipv4(field_info *fi, ws_in4_addr value);
334 | static void
335 | proto_tree_set_ipv6(field_info *fi, const ws_in6_addr* value);
336 | static void
337 | proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
338 | static void
339 | proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
340 | static void
341 | proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr);
342 | static void
343 | proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding);
344 | static void
345 | proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, int length);
346 | static void
347 | proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
348 | static void
349 | proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, int length);
350 | static void
351 | proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
352 | static void
353 | proto_tree_set_boolean(field_info *fi, uint64_t value);
354 | static void
355 | proto_tree_set_float(field_info *fi, float value);
356 | static void
357 | proto_tree_set_double(field_info *fi, double value);
358 | static void
359 | proto_tree_set_uint(field_info *fi, uint32_t value);
360 | static void
361 | proto_tree_set_int(field_info *fi, int32_t value);
362 | static void
363 | proto_tree_set_uint64(field_info *fi, uint64_t value);
364 | static void
365 | proto_tree_set_int64(field_info *fi, int64_t value);
366 | static void
367 | proto_tree_set_eui64(field_info *fi, const uint64_t value);
368 | static void
369 | proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding);
370 |
371 | /* Handle type length mismatch (now filterable) expert info */
372 | static int proto_type_length_mismatch;
373 | static expert_field ei_type_length_mismatch_error;
374 | static expert_field ei_type_length_mismatch_warn;
375 | static void register_type_length_mismatch(void);
376 |
377 | /* Handle byte array string decoding errors with expert info */
378 | static int proto_byte_array_string_decoding_error;
379 | static expert_field ei_byte_array_string_decoding_failed_error;
380 | static void register_byte_array_string_decodinws_error(void);
381 |
382 | /* Handle date and time string decoding errors with expert info */
383 | static int proto_date_time_string_decoding_error;
384 | static expert_field ei_date_time_string_decoding_failed_error;
385 | static void register_date_time_string_decodinws_error(void);
386 |
387 | /* Handle string errors expert info */
388 | static int proto_string_errors;
389 | static expert_field ei_string_trailing_characters;
390 | static void register_string_errors(void);
391 |
392 | static int proto_register_field_init(header_field_info *hfinfo, const int parent);
393 |
394 | /* special-case header field used within proto.c */
395 | static header_field_info hfi_text_only =
396 | { "Text item", "text", FT_NONE, BASE_NONE, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) };
397 | int hf_text_only;
398 |
399 | /* Structure for information about a protocol */
400 | struct _protocol {
401 | const char *name; /* long description */
402 | const char *short_name; /* short description */
403 | const char *filter_name; /* name of this protocol in filters */
404 | GPtrArray *fields; /* fields for this protocol */
405 | int proto_id; /* field ID for this protocol */
406 | bool_Bool is_enabled; /* true if protocol is enabled */
407 | bool_Bool enabled_by_default; /* true if protocol is enabled by default */
408 | bool_Bool can_toggle; /* true if is_enabled can be changed */
409 | int parent_proto_id; /* Used to identify "pino"s (Protocol In Name Only).
410 | For dissectors that need a protocol name so they
411 | can be added to a dissector table, but use the
412 | parent_proto_id for things like enable/disable */
413 | GList *heur_list; /* Heuristic dissectors associated with this protocol */
414 | };
415 |
416 | /* List of all protocols */
417 | static GList *protocols;
418 |
419 | /* Structure stored for deregistered g_slice */
420 | struct g_slice_data {
421 | size_t block_size;
422 | void *mem_block;
423 | };
424 |
425 | /* Deregistered fields */
426 | static GPtrArray *deregistered_fields;
427 | static GPtrArray *deregistered_data;
428 | static GPtrArray *deregistered_slice;
429 |
430 | /* indexed by prefix, contains initializers */
431 | static GHashTable* prefixes;
432 |
433 | /* Contains information about a field when a dissector calls
434 | * proto_tree_add_item. */
435 | #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)))
436 | #define FIELD_INFO_FREE(pool, fi)wmem_free(pool, fi) wmem_free(pool, fi)
437 |
438 | /* Contains the space for proto_nodes. */
439 | #define PROTO_NODE_INIT(node)node->first_child = ((void*)0); node->last_child = ((void *)0); node->next = ((void*)0); \
440 | node->first_child = NULL((void*)0); \
441 | node->last_child = NULL((void*)0); \
442 | node->next = NULL((void*)0);
443 |
444 | #define PROTO_NODE_FREE(pool, node)wmem_free(pool, node) \
445 | wmem_free(pool, node)
446 |
447 | /* String space for protocol and field items for the GUI */
448 | #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; \
449 | il = wmem_new(pool, item_label_t)((item_label_t*)wmem_alloc((pool), sizeof(item_label_t))); \
450 | il->value_pos = 0; \
451 | il->value_len = 0;
452 | #define ITEM_LABEL_FREE(pool, il)wmem_free(pool, il); \
453 | wmem_free(pool, il);
454 |
455 | #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", 455, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 455, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((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!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex]; \
456 | if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug) \
457 | ws_error("Unregistered hf! index=%d", hfindex)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 457 , __func__, "Unregistered hf! index=%d", hfindex); \
458 | 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", 458, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))); \
459 | 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", 459, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))); \
460 | hfinfo = gpa_hfinfo.hfi[hfindex];
461 |
462 | #define PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000) (300000+PRE_ALLOC_EXPERT_FIELDS_MEM5000)
463 |
464 | /* List which stores protocols and fields that have been registered */
465 | typedef struct _gpa_hfinfo_t {
466 | uint32_t len;
467 | uint32_t allocated_len;
468 | header_field_info **hfi;
469 | } gpa_hfinfo_t;
470 |
471 | static gpa_hfinfo_t gpa_hfinfo;
472 |
473 | /* Hash table of abbreviations and IDs */
474 | static wmem_map_t *gpa_name_map;
475 | static header_field_info *same_name_hfinfo;
476 |
477 | /* Hash table protocol aliases. const char * -> const char * */
478 | static GHashTable *gpa_protocol_aliases;
479 |
480 | /*
481 | * We're called repeatedly with the same field name when sorting a column.
482 | * Cache our last gpa_name_map hit for faster lookups.
483 | */
484 | static char *last_field_name;
485 | static header_field_info *last_hfinfo;
486 |
487 | /* Points to the first element of an array of bits, indexed by
488 | a subtree item type; that array element is true if subtrees of
489 | an item of that type are to be expanded. */
490 | static uint32_t *tree_is_expanded;
491 |
492 | /* Number of elements in that array. The entry with index 0 is not used. */
493 | int num_tree_types = 1;
494 |
495 | /* Name hashtables for fast detection of duplicate names */
496 | static GHashTable* proto_names;
497 | static GHashTable* proto_short_names;
498 | static GHashTable* proto_filter_names;
499 |
500 | static const char * const reserved_filter_names[] = {
501 | /* Display filter keywords. */
502 | "eq",
503 | "ne",
504 | "all_eq",
505 | "any_eq",
506 | "all_ne",
507 | "any_ne",
508 | "gt",
509 | "ge",
510 | "lt",
511 | "le",
512 | "bitand",
513 | "bitwise_and",
514 | "contains",
515 | "matches",
516 | "not",
517 | "and",
518 | "or",
519 | "xor",
520 | "in",
521 | "any",
522 | "all",
523 | "true",
524 | "false",
525 | "nan",
526 | "inf",
527 | "infinity",
528 | NULL((void*)0)
529 | };
530 |
531 | static GHashTable *proto_reserved_filter_names;
532 | static GQueue* saved_dir_queue;
533 |
534 | static int
535 | proto_compare_name(const void *p1_arg, const void *p2_arg)
536 | {
537 | const protocol_t *p1 = (const protocol_t *)p1_arg;
538 | const protocol_t *p2 = (const protocol_t *)p2_arg;
539 |
540 | return g_ascii_strcasecmp(p1->short_name, p2->short_name);
541 | }
542 |
543 | static GSList *dissector_plugins;
544 |
545 | #ifdef HAVE_PLUGINS1
546 | void
547 | proto_register_plugin(const proto_plugin *plug)
548 | {
549 | dissector_plugins = g_slist_prepend(dissector_plugins, (proto_plugin *)plug);
550 | }
551 | #else /* HAVE_PLUGINS */
552 | void
553 | proto_register_plugin(const proto_plugin *plug _U___attribute__((unused)))
554 | {
555 | ws_warning("proto_register_plugin: built without support for binary plugins")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 555, __func__, "proto_register_plugin: built without support for binary plugins" ); } } while (0);
556 | }
557 | #endif /* HAVE_PLUGINS */
558 |
559 | static void
560 | call_plugin_register_protoinfo(void *data, void *user_data _U___attribute__((unused)))
561 | {
562 | proto_plugin *plug = (proto_plugin *)data;
563 |
564 | if (plug->register_protoinfo) {
565 | plug->register_protoinfo();
566 | }
567 | }
568 |
569 | static void
570 | call_plugin_register_handoff(void *data, void *user_data _U___attribute__((unused)))
571 | {
572 | proto_plugin *plug = (proto_plugin *)data;
573 |
574 | if (plug->register_handoff) {
575 | plug->register_handoff();
576 | }
577 | }
578 |
579 | void proto_pre_init(void)
580 | {
581 | saved_dir_queue = g_queue_new();
582 |
583 | proto_names = g_hash_table_new(wmem_str_hash, g_str_equal);
584 | proto_short_names = g_hash_table_new(wmem_str_hash, g_str_equal);
585 | proto_filter_names = g_hash_table_new(wmem_str_hash, g_str_equal);
586 |
587 | proto_reserved_filter_names = g_hash_table_new(wmem_str_hash, g_str_equal);
588 | for (const char* const * ptr = reserved_filter_names; *ptr != NULL((void*)0); ptr++) {
589 | /* GHashTable has no key destructor so the cast is safe. */
590 | g_hash_table_add(proto_reserved_filter_names, *(char**)ptr);
591 | }
592 |
593 | gpa_hfinfo.len = 0;
594 | gpa_hfinfo.allocated_len = 0;
595 | gpa_hfinfo.hfi = NULL((void*)0);
596 | gpa_name_map = wmem_map_new(wmem_epan_scope(), wmem_str_hash, g_str_equal);
597 | wmem_map_reserve(gpa_name_map, PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
598 | gpa_protocol_aliases = g_hash_table_new(wmem_str_hash, g_str_equal);
599 | deregistered_fields = g_ptr_array_new();
600 | deregistered_data = g_ptr_array_new();
601 | deregistered_slice = g_ptr_array_new();
602 | }
603 |
604 | /* initialize data structures and register protocols and fields */
605 | void
606 | proto_init(GSList *register_all_plugin_protocols_list,
607 | GSList *register_all_plugin_handoffs_list,
608 | register_entity_func register_func, register_entity_func handoff_func,
609 | register_cb cb,
610 | void *client_data)
611 | {
612 | /* Initialize the ftype subsystem */
613 | ftypes_initialize();
614 |
615 | /* Initialize the address type subsystem */
616 | address_types_initialize();
617 |
618 | /* Register one special-case FT_TEXT_ONLY field for use when
619 | converting wireshark to new-style proto_tree. These fields
620 | are merely strings on the GUI tree; they are not filterable */
621 | hf_text_only = proto_register_field_init(&hfi_text_only, -1);
622 |
623 | /* Register the pseudo-protocols used for exceptions. */
624 | register_show_exception();
625 | register_type_length_mismatch();
626 | register_byte_array_string_decodinws_error();
627 | register_date_time_string_decodinws_error();
628 | register_string_errors();
629 | ftypes_register_pseudofields();
630 | col_register_protocol();
631 |
632 | /* Have each built-in dissector register its protocols, fields,
633 | dissector tables, and dissectors to be called through a
634 | handle, and do whatever one-time initialization it needs to
635 | do. */
636 | if (register_func != NULL((void*)0))
637 | register_func(cb, client_data);
638 |
639 | /* Now call the registration routines for all epan plugins. */
640 | for (GSList *l = register_all_plugin_protocols_list; l != NULL((void*)0); l = l->next) {
641 | ((void (*)(register_cb, void *))l->data)(cb, client_data);
642 | }
643 |
644 | /* Now call the registration routines for all dissector plugins. */
645 | if (cb)
646 | (*cb)(RA_PLUGIN_REGISTER, NULL((void*)0), client_data);
647 | g_slist_foreach(dissector_plugins, call_plugin_register_protoinfo, NULL((void*)0));
648 |
649 | /* Now call the "handoff registration" routines of all built-in
650 | dissectors; those routines register the dissector in other
651 | dissectors' handoff tables, and fetch any dissector handles
652 | they need. */
653 | if (handoff_func != NULL((void*)0))
654 | handoff_func(cb, client_data);
655 |
656 | /* Now do the same with epan plugins. */
657 | for (GSList *l = register_all_plugin_handoffs_list; l != NULL((void*)0); l = l->next) {
658 | ((void (*)(register_cb, void *))l->data)(cb, client_data);
659 | }
660 |
661 | /* Now do the same with dissector plugins. */
662 | if (cb)
663 | (*cb)(RA_PLUGIN_HANDOFF, NULL((void*)0), client_data);
664 | g_slist_foreach(dissector_plugins, call_plugin_register_handoff, NULL((void*)0));
665 |
666 | /* sort the protocols by protocol name */
667 | protocols = g_list_sort(protocols, proto_compare_name);
668 |
669 | /* sort the dissector handles in dissector tables (for -G reports
670 | * and -d error messages. The GUI sorts the handles itself.) */
671 | packet_all_tables_sort_handles();
672 |
673 | /* We've assigned all the subtree type values; allocate the array
674 | for them, and zero it out. */
675 | 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 )));
676 | }
677 |
678 | static void
679 | proto_cleanup_base(void)
680 | {
681 | protocol_t *protocol;
682 | header_field_info *hfinfo;
683 |
684 | /* Free the abbrev/ID hash table */
685 | if (gpa_name_map) {
686 | // XXX - We don't have a wmem_map_destroy, but
687 | // it does get cleaned up when epan scope is
688 | // destroyed
689 | //g_hash_table_destroy(gpa_name_map);
690 | gpa_name_map = NULL((void*)0);
691 | }
692 | if (gpa_protocol_aliases) {
693 | g_hash_table_destroy(gpa_protocol_aliases);
694 | gpa_protocol_aliases = NULL((void*)0);
695 | }
696 | g_free(last_field_name)(__builtin_object_size ((last_field_name), 0) != ((size_t) - 1 )) ? g_free_sized (last_field_name, __builtin_object_size ((last_field_name ), 0)) : (g_free) (last_field_name);
697 | last_field_name = NULL((void*)0);
698 |
699 | while (protocols) {
700 | protocol = (protocol_t *)protocols->data;
701 | 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", 701 , __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", 701, "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", 701, "gpa_hfinfo.hfi[protocol->proto_id] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[protocol-> proto_id];;
702 | 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", 702, "protocol->proto_id == hfinfo->id" ))));
703 |
704 | 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);
705 | if (protocol->parent_proto_id != -1) {
706 | // pino protocol
707 | DISSECTOR_ASSERT(protocol->fields == NULL)((void) ((protocol->fields == ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 707, "protocol->fields == ((void*)0)" )))); //helpers should not have any registered fields
708 | 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" , 708, "protocol->heur_list == ((void*)0)")))); //helpers should not have a heuristic list
709 | } else {
710 | if (protocol->fields) {
711 | g_ptr_array_free(protocol->fields, true1);
712 | }
713 | g_list_free(protocol->heur_list);
714 | }
715 | protocols = g_list_remove(protocols, protocol);
716 | g_free(protocol)(__builtin_object_size ((protocol), 0) != ((size_t) - 1)) ? g_free_sized (protocol, __builtin_object_size ((protocol), 0)) : (g_free) (protocol);
717 | }
718 |
719 | if (proto_names) {
720 | g_hash_table_destroy(proto_names);
721 | proto_names = NULL((void*)0);
722 | }
723 |
724 | if (proto_short_names) {
725 | g_hash_table_destroy(proto_short_names);
726 | proto_short_names = NULL((void*)0);
727 | }
728 |
729 | if (proto_filter_names) {
730 | g_hash_table_destroy(proto_filter_names);
731 | proto_filter_names = NULL((void*)0);
732 | }
733 |
734 | if (proto_reserved_filter_names) {
735 | g_hash_table_destroy(proto_reserved_filter_names);
736 | proto_reserved_filter_names = NULL((void*)0);
737 | }
738 |
739 | if (gpa_hfinfo.allocated_len) {
740 | gpa_hfinfo.len = 0;
741 | gpa_hfinfo.allocated_len = 0;
742 | g_free(gpa_hfinfo.hfi)(__builtin_object_size ((gpa_hfinfo.hfi), 0) != ((size_t) - 1 )) ? g_free_sized (gpa_hfinfo.hfi, __builtin_object_size ((gpa_hfinfo .hfi), 0)) : (g_free) (gpa_hfinfo.hfi);
743 | gpa_hfinfo.hfi = NULL((void*)0);
744 | }
745 |
746 | if (deregistered_fields) {
747 | g_ptr_array_free(deregistered_fields, true1);
748 | deregistered_fields = NULL((void*)0);
749 | }
750 |
751 | if (deregistered_data) {
752 | g_ptr_array_free(deregistered_data, true1);
753 | deregistered_data = NULL((void*)0);
754 | }
755 |
756 | if (deregistered_slice) {
757 | g_ptr_array_free(deregistered_slice, true1);
758 | deregistered_slice = NULL((void*)0);
759 | }
760 |
761 | g_free(tree_is_expanded)(__builtin_object_size ((tree_is_expanded), 0) != ((size_t) - 1)) ? g_free_sized (tree_is_expanded, __builtin_object_size ( (tree_is_expanded), 0)) : (g_free) (tree_is_expanded);
762 | tree_is_expanded = NULL((void*)0);
763 |
764 | if (prefixes)
765 | g_hash_table_destroy(prefixes);
766 |
767 | if (saved_dir_queue != NULL((void*)0)) {
768 | g_queue_clear_full(saved_dir_queue, g_free);
769 | g_queue_free(saved_dir_queue);
770 | saved_dir_queue = NULL((void*)0);
771 | }
772 | }
773 |
774 | void
775 | proto_cleanup(void)
776 | {
777 | proto_free_deregistered_fields();
778 | proto_cleanup_base();
779 |
780 | g_slist_free(dissector_plugins);
781 | dissector_plugins = NULL((void*)0);
782 | }
783 |
784 | static bool_Bool
785 | ws_pushd(const char* dir)
786 | {
787 | //Save the current working directory
788 | const char* save_wd = get_current_working_dir();
789 | if (save_wd != NULL((void*)0))
790 | g_queue_push_head(saved_dir_queue, g_strdup(save_wd)g_strdup_inline (save_wd));
791 |
792 | //Change to the new one
793 | #ifdef _WIN32
794 | SetCurrentDirectory(utf_8to16(dir));
795 | return true1;
796 | #else
797 | return (chdir(dir) == 0);
798 | #endif
799 | }
800 |
801 | static bool_Bool
802 | ws_popd(void)
803 | {
804 | int ret = 0;
805 | char* saved_wd = g_queue_pop_head(saved_dir_queue);
806 | if (saved_wd == NULL((void*)0))
807 | return false0;
808 |
809 | //Restore the previous one
810 | #ifdef _WIN32
811 | SetCurrentDirectory(utf_8to16(saved_wd));
812 | #else
813 | ret = chdir(saved_wd);
814 | #endif
815 | g_free(saved_wd)(__builtin_object_size ((saved_wd), 0) != ((size_t) - 1)) ? g_free_sized (saved_wd, __builtin_object_size ((saved_wd), 0)) : (g_free) (saved_wd);
816 | return (ret == 0);
817 | }
818 |
819 | void
820 | proto_execute_in_directory(const char* dir, proto_execute_in_directory_func func, void* param)
821 | {
822 | if (ws_pushd(dir))
823 | {
824 | func(param);
825 | ws_popd();
826 | }
827 | }
828 |
829 | static bool_Bool
830 | // NOLINTNEXTLINE(misc-no-recursion)
831 | proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
832 | void *data)
833 | {
834 | proto_node *pnode = tree;
835 | proto_node *child;
836 | proto_node *current;
837 |
838 | if (func(pnode, data))
839 | return true1;
840 |
841 | child = pnode->first_child;
842 | while (child != NULL((void*)0)) {
843 | /*
844 | * The routine we call might modify the child, e.g. by
845 | * freeing it, so we get the child's successor before
846 | * calling that routine.
847 | */
848 | current = child;
849 | child = current->next;
850 | // We recurse here, but we're limited by prefs.gui_max_tree_depth
851 | if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
852 | return true1;
853 | }
854 |
855 | return false0;
856 | }
857 |
858 | void
859 | proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
860 | void *data)
861 | {
862 | proto_node *node = tree;
863 | proto_node *current;
864 |
865 | if (!node)
866 | return;
867 |
868 | node = node->first_child;
869 | while (node != NULL((void*)0)) {
870 | current = node;
871 | node = current->next;
872 | func((proto_tree *)current, data);
873 | }
874 | }
875 |
876 | static void
877 | free_GPtrArray_value(void *key, void *value, void *user_data _U___attribute__((unused)))
878 | {
879 | GPtrArray *ptrs = (GPtrArray *)value;
880 | int hfid = GPOINTER_TO_UINT(key)((guint) (gulong) (key));
881 | header_field_info *hfinfo;
882 |
883 | 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", 883, __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", 883, "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", 883, "gpa_hfinfo.hfi[hfid] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[hfid];;
884 | if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
885 | /* when a field is referenced by a filter this also
886 | affects the refcount for the parent protocol so we need
887 | to adjust the refcount for the parent as well
888 | */
889 | if (hfinfo->parent != -1) {
890 | header_field_info *parent_hfinfo;
891 | 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", 891 , __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", 891, "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", 891, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)" , "Unregistered hf!")))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo ->parent];;
892 | parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
893 | }
894 | hfinfo->ref_type = HF_REF_TYPE_NONE;
895 | }
896 |
897 | g_ptr_array_free(ptrs, true1);
898 | }
899 |
900 | static void
901 | proto_tree_free_node(proto_node *node, void *data _U___attribute__((unused)))
902 | {
903 | field_info *finfo = PNODE_FINFO(node)((node)->finfo);
904 |
905 | proto_tree_children_foreach(node, proto_tree_free_node, NULL((void*)0));
906 |
907 | if (finfo) {
908 | fvalue_free(finfo->value);
909 | finfo->value = NULL((void*)0);
910 | }
911 | }
912 |
913 | void
914 | proto_tree_reset(proto_tree *tree)
915 | {
916 | tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
917 |
918 | proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
919 |
920 | /* free tree data */
921 | if (tree_data->interesting_hfids) {
922 | /* Free all the GPtrArray's in the interesting_hfids hash. */
923 | g_hash_table_foreach(tree_data->interesting_hfids,
924 | free_GPtrArray_value, NULL((void*)0));
925 |
926 | /* And then remove all values. */
927 | g_hash_table_remove_all(tree_data->interesting_hfids);
928 | }
929 |
930 | /* Reset track of the number of children */
931 | tree_data->count = 0;
932 |
933 | /* Reset our loop checks */
934 | tree_data->idle_count_ds_tvb = NULL((void*)0);
935 | tree_data->max_start = 0;
936 | tree_data->start_idle_count = 0;
937 |
938 | PROTO_NODE_INIT(tree)tree->first_child = ((void*)0); tree->last_child = ((void *)0); tree->next = ((void*)0);;
939 | }
940 |
941 | /* frees the resources that the dissection a proto_tree uses */
942 | void
943 | proto_tree_free(proto_tree *tree)
944 | {
945 | tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
946 |
947 | proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
948 |
949 | /* free tree data */
950 | if (tree_data->interesting_hfids) {
951 | /* Free all the GPtrArray's in the interesting_hfids hash. */
952 | g_hash_table_foreach(tree_data->interesting_hfids,
953 | free_GPtrArray_value, NULL((void*)0));
954 |
955 | /* And then destroy the hash. */
956 | g_hash_table_destroy(tree_data->interesting_hfids);
957 | }
958 |
959 | 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);
960 |
961 | g_slice_free(proto_tree, tree)do { if (1) g_slice_free1 (sizeof (proto_tree), (tree)); else (void) ((proto_tree*) 0 == (tree)); } while (0);
962 | }
963 |
964 | /* Is the parsing being done for a visible proto_tree or an invisible one?
965 | * By setting this correctly, the proto_tree creation is sped up by not
966 | * having to call vsnprintf and copy strings around.
967 | */
968 | bool_Bool
969 | proto_tree_set_visible(proto_tree *tree, bool_Bool visible)
970 | {
971 | bool_Bool old_visible = PTREE_DATA(tree)((tree)->tree_data)->visible;
972 |
973 | PTREE_DATA(tree)((tree)->tree_data)->visible = visible;
974 |
975 | return old_visible;
976 | }
977 |
978 | void
979 | proto_tree_set_fake_protocols(proto_tree *tree, bool_Bool fake_protocols)
980 | {
981 | if (tree)
982 | PTREE_DATA(tree)((tree)->tree_data)->fake_protocols = fake_protocols;
983 | }
984 |
985 | /* Assume dissector set only its protocol fields.
986 | This function is called by dissectors and allows the speeding up of filtering
987 | in wireshark; if this function returns false it is safe to reset tree to NULL
988 | and thus skip calling most of the expensive proto_tree_add_...()
989 | functions.
990 | If the tree is visible we implicitly assume the field is referenced.
991 | */
992 | bool_Bool
993 | proto_field_is_referenced(proto_tree *tree, int proto_id)
994 | {
995 | register header_field_info *hfinfo;
996 |
997 |
998 | if (!tree)
999 | return false0;
1000 |
1001 | if (PTREE_DATA(tree)((tree)->tree_data)->visible)
1002 | return true1;
1003 |
1004 | 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", 1004, __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", 1004, "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", 1004, "gpa_hfinfo.hfi[proto_id] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];;
1005 | if (hfinfo->ref_type != HF_REF_TYPE_NONE)
1006 | return true1;
1007 |
1008 | if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)
1009 | return true1;
1010 |
1011 | return false0;
1012 | }
1013 |
1014 |
1015 | /* Finds a record in the hfinfo array by id. */
1016 | header_field_info *
1017 | proto_registrar_get_nth(unsigned hfindex)
1018 | {
1019 | register header_field_info *hfinfo;
1020 |
1021 | 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", 1021, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 1021, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 1021, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
1022 | return hfinfo;
1023 | }
1024 |
1025 |
1026 | /* Prefix initialization
1027 | * this allows for a dissector to register a display filter name prefix
1028 | * so that it can delay the initialization of the hf array as long as
1029 | * possible.
1030 | */
1031 |
1032 | /* compute a hash for the part before the dot of a display filter */
1033 | static unsigned
1034 | prefix_hash (const void *key) {
1035 | /* end the string at the dot and compute its hash */
1036 | char* copy = g_strdup((const char *)key)g_strdup_inline ((const char *)key);
1037 | char* c = copy;
1038 | unsigned tmp;
1039 |
1040 | for (; *c; c++) {
1041 | if (*c == '.') {
1042 | *c = 0;
1043 | break;
1044 | }
1045 | }
1046 |
1047 | tmp = wmem_str_hash(copy);
1048 | g_free(copy)(__builtin_object_size ((copy), 0) != ((size_t) - 1)) ? g_free_sized (copy, __builtin_object_size ((copy), 0)) : (g_free) (copy);
1049 | return tmp;
1050 | }
1051 |
1052 | /* are both strings equal up to the end or the dot? */
1053 | static gboolean
1054 | prefix_equal (const void *ap, const void *bp) {
1055 | const char* a = (const char *)ap;
1056 | const char* b = (const char *)bp;
1057 |
1058 | do {
1059 | char ac = *a++;
1060 | char bc = *b++;
1061 |
1062 | if ( (ac == '.' || ac == '\0') && (bc == '.' || bc == '\0') ) return TRUE(!(0));
1063 |
1064 | if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE(0);
1065 | if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE(0);
1066 |
1067 | if (ac != bc) return FALSE(0);
1068 | } while (1);
1069 |
1070 | return FALSE(0);
1071 | }
1072 |
1073 | /* Register a new prefix for "delayed" initialization of field arrays */
1074 | void
1075 | proto_register_prefix(const char *prefix, prefix_initializer_t pi ) {
1076 | if (! prefixes ) {
1077 | prefixes = g_hash_table_new(prefix_hash, prefix_equal);
1078 | }
1079 |
1080 | g_hash_table_insert(prefixes, (void *)prefix, (void *)pi);
1081 | }
1082 |
1083 | /* helper to call all prefix initializers */
1084 | static gboolean
1085 | initialize_prefix(void *k, void *v, void *u _U___attribute__((unused))) {
1086 | ((prefix_initializer_t)v)((const char *)k);
1087 | return TRUE(!(0));
1088 | }
1089 |
1090 | /** Initialize every remaining uninitialized prefix. */
1091 | void
1092 | proto_initialize_all_prefixes(void) {
1093 | g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL((void*)0));
1094 | }
1095 |
1096 | /* Finds a record in the hfinfo array by name.
1097 | * If it fails to find it in the already registered fields,
1098 | * it tries to find and call an initializer in the prefixes
1099 | * table and if so it looks again.
1100 | */
1101 |
1102 | header_field_info *
1103 | proto_registrar_get_byname(const char *field_name)
1104 | {
1105 | header_field_info *hfinfo;
1106 | prefix_initializer_t pi;
1107 |
1108 | if (!field_name)
1109 | return NULL((void*)0);
1110 |
1111 | if (g_strcmp0(field_name, last_field_name) == 0) {
1112 | return last_hfinfo;
1113 | }
1114 |
1115 | hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1116 |
1117 | if (hfinfo) {
1118 | g_free(last_field_name)(__builtin_object_size ((last_field_name), 0) != ((size_t) - 1 )) ? g_free_sized (last_field_name, __builtin_object_size ((last_field_name ), 0)) : (g_free) (last_field_name);
1119 | last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1120 | last_hfinfo = hfinfo;
1121 | return hfinfo;
1122 | }
1123 |
1124 | if (!prefixes)
1125 | return NULL((void*)0);
1126 |
1127 | if ((pi = (prefix_initializer_t)g_hash_table_lookup(prefixes, field_name) ) != NULL((void*)0)) {
1128 | pi(field_name);
1129 | g_hash_table_remove(prefixes, field_name);
1130 | } else {
1131 | return NULL((void*)0);
1132 | }
1133 |
1134 | hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1135 |
1136 | if (hfinfo) {
1137 | g_free(last_field_name)(__builtin_object_size ((last_field_name), 0) != ((size_t) - 1 )) ? g_free_sized (last_field_name, __builtin_object_size ((last_field_name ), 0)) : (g_free) (last_field_name);
1138 | last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1139 | last_hfinfo = hfinfo;
1140 | }
1141 | return hfinfo;
1142 | }
1143 |
1144 | header_field_info*
1145 | proto_registrar_get_byalias(const char *alias_name)
1146 | {
1147 | if (!alias_name) {
1148 | return NULL((void*)0);
1149 | }
1150 |
1151 | /* Find our aliased protocol. */
1152 | char *an_copy = g_strdup(alias_name)g_strdup_inline (alias_name);
1153 | char *dot = strchr(an_copy, '.');
1154 | if (dot) {
1155 | *dot = '\0';
1156 | }
1157 | const char *proto_pfx = (const char *) g_hash_table_lookup(gpa_protocol_aliases, an_copy);
1158 | if (!proto_pfx) {
1159 | g_free(an_copy)(__builtin_object_size ((an_copy), 0) != ((size_t) - 1)) ? g_free_sized (an_copy, __builtin_object_size ((an_copy), 0)) : (g_free) ( an_copy);
1160 | return NULL((void*)0);
1161 | }
1162 |
1163 | /* Construct our aliased field and look it up. */
1164 | GString *filter_name = g_string_new(proto_pfx);
1165 | if (dot) {
1166 | g_string_append_printf(filter_name, ".%s", dot+1);
1167 | }
1168 | header_field_info *hfinfo = proto_registrar_get_byname(filter_name->str);
1169 | g_free(an_copy)(__builtin_object_size ((an_copy), 0) != ((size_t) - 1)) ? g_free_sized (an_copy, __builtin_object_size ((an_copy), 0)) : (g_free) ( an_copy);
1170 | 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)))));
1171 |
1172 | return hfinfo;
1173 | }
1174 |
1175 | int
1176 | proto_registrar_get_id_byname(const char *field_name)
1177 | {
1178 | header_field_info *hfinfo;
1179 |
1180 | hfinfo = proto_registrar_get_byname(field_name);
1181 |
1182 | if (!hfinfo)
1183 | return -1;
1184 |
1185 | return hfinfo->id;
1186 | }
1187 |
1188 | static int
1189 | label_strcat_flags(const header_field_info *hfinfo)
1190 | {
1191 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) & BASE_STR_WSP)
1192 | return FORMAT_LABEL_REPLACE_SPACE(0x1 << 0);
1193 |
1194 | return 0;
1195 | }
1196 |
1197 | static char *
1198 | format_bytes_hfinfo_maxlen(wmem_allocator_t *scope, const header_field_info *hfinfo,
1199 | const uint8_t *bytes, unsigned length, size_t max_str_len)
1200 | {
1201 | char *str = NULL((void*)0);
1202 | const uint8_t *p;
1203 | bool_Bool is_printable;
1204 |
1205 | if (bytes) {
1206 | if (hfinfo->display & BASE_SHOW_UTF_8_PRINTABLE0x00020000) {
1207 | /*
1208 | * If all bytes are valid and printable UTF-8, show the
1209 | * bytes as a string - in quotes to indicate that it's
1210 | * a string.
1211 | */
1212 | if (isprint_utf8_string((const char*)bytes, length)) {
1213 | str = wmem_strdup_printf(scope, "\"%.*s\"",
1214 | (int)length, bytes);
1215 | return str;
1216 | }
1217 | } else if (hfinfo->display & BASE_SHOW_ASCII_PRINTABLE0x00010000) {
1218 | /*
1219 | * Check whether all bytes are printable.
1220 | */
1221 | is_printable = true1;
1222 | for (p = bytes; p < bytes+length; p++) {
1223 | if (!g_ascii_isprint(*p)((g_ascii_table[(guchar) (*p)] & G_ASCII_PRINT) != 0)) {
1224 | /* Not printable. */
1225 | is_printable = false0;
1226 | break;
1227 | }
1228 | }
1229 |
1230 | /*
1231 | * If all bytes are printable ASCII, show the bytes
1232 | * as a string - in quotes to indicate that it's
1233 | * a string.
1234 | */
1235 | if (is_printable) {
1236 | str = wmem_strdup_printf(scope, "\"%.*s\"",
1237 | (int)length, bytes);
1238 | return str;
1239 | }
1240 | }
1241 |
1242 | /*
1243 | * Either it's not printable ASCII, or we don't care whether
1244 | * it's printable ASCII; show it as hex bytes.
1245 | */
1246 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
1247 | case SEP_DOT:
1248 | str = bytes_to_str_punct_maxlen(scope, bytes, length, '.', max_str_len/3);
1249 | break;
1250 | case SEP_DASH:
1251 | str = bytes_to_str_punct_maxlen(scope, bytes, length, '-', max_str_len/3);
1252 | break;
1253 | case SEP_COLON:
1254 | str = bytes_to_str_punct_maxlen(scope, bytes, length, ':', max_str_len/3);
1255 | break;
1256 | case SEP_SPACE:
1257 | str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1258 | break;
1259 | case BASE_NONE:
1260 | default:
1261 | if (prefs.display_byte_fields_with_spaces) {
1262 | str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1263 | } else {
1264 | str = bytes_to_str_maxlen(scope, bytes, length, max_str_len/2);
1265 | }
1266 | break;
1267 | }
1268 | }
1269 | else {
1270 | if (hfinfo->display & BASE_ALLOW_ZERO0x00000800) {
1271 | str = wmem_strdup(scope, "<none>");
1272 | } else {
1273 | str = wmem_strdup(scope, "<MISSING>");
1274 | }
1275 | }
1276 | return str;
1277 | }
1278 |
1279 | static char *
1280 | format_bytes_hfinfo(wmem_allocator_t *scope, const header_field_info *hfinfo,
1281 | const uint8_t *bytes, unsigned length)
1282 | {
1283 | return format_bytes_hfinfo_maxlen(scope, hfinfo, bytes, length, ITEM_LABEL_LENGTH240);
1284 | }
1285 |
1286 | static void
1287 | ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
1288 | {
1289 | subtree_lvl *pushed_tree;
1290 |
1291 | 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" , 1291, "ptvc->pushed_tree_max <= 256-8"))));
1292 | ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER8;
1293 |
1294 | pushed_tree = (subtree_lvl *)wmem_realloc(ptvc->scope, (void *)ptvc->pushed_tree, sizeof(subtree_lvl) * ptvc->pushed_tree_max);
1295 | DISSECTOR_ASSERT(pushed_tree != NULL)((void) ((pushed_tree != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1295, "pushed_tree != ((void*)0)" ))));
1296 | ptvc->pushed_tree = pushed_tree;
1297 | }
1298 |
1299 | static void
1300 | ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
1301 | {
1302 | ptvc->pushed_tree = NULL((void*)0);
1303 | ptvc->pushed_tree_max = 0;
1304 | 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", 1304, "ptvc->pushed_tree_index == 0" ))));
1305 | ptvc->pushed_tree_index = 0;
1306 | }
1307 |
1308 | /* Allocates an initializes a ptvcursor_t with 3 variables:
1309 | * proto_tree, tvbuff, and offset. */
1310 | ptvcursor_t *
1311 | ptvcursor_new(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb, unsigned offset)
1312 | {
1313 | ptvcursor_t *ptvc;
1314 |
1315 | ptvc = wmem_new(scope, ptvcursor_t)((ptvcursor_t*)wmem_alloc((scope), sizeof(ptvcursor_t)));
1316 | ptvc->scope = scope;
1317 | ptvc->tree = tree;
1318 | ptvc->tvb = tvb;
1319 | ptvc->offset = offset;
1320 | ptvc->pushed_tree = NULL((void*)0);
1321 | ptvc->pushed_tree_max = 0;
1322 | ptvc->pushed_tree_index = 0;
1323 | return ptvc;
1324 | }
1325 |
1326 |
1327 | /* Frees memory for ptvcursor_t, but nothing deeper than that. */
1328 | void
1329 | ptvcursor_free(ptvcursor_t *ptvc)
1330 | {
1331 | ptvcursor_free_subtree_levels(ptvc);
1332 | wmem_free(ptvc->scope, ptvc);
1333 | }
1334 |
1335 | /* Returns tvbuff. */
1336 | tvbuff_t *
1337 | ptvcursor_tvbuff(ptvcursor_t *ptvc)
1338 | {
1339 | return ptvc->tvb;
1340 | }
1341 |
1342 | /* Returns current offset. */
1343 | unsigned
1344 | ptvcursor_current_offset(ptvcursor_t *ptvc)
1345 | {
1346 | return ptvc->offset;
1347 | }
1348 |
1349 | proto_tree *
1350 | ptvcursor_tree(ptvcursor_t *ptvc)
1351 | {
1352 | if (!ptvc)
1353 | return NULL((void*)0);
1354 |
1355 | return ptvc->tree;
1356 | }
1357 |
1358 | void
1359 | ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
1360 | {
1361 | ptvc->tree = tree;
1362 | }
1363 |
1364 | /* creates a subtree, sets it as the working tree and pushes the old working tree */
1365 | proto_tree *
1366 | ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1367 | {
1368 | subtree_lvl *subtree;
1369 | if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
1370 | ptvcursor_new_subtree_levels(ptvc);
1371 |
1372 | subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1373 | subtree->tree = ptvc->tree;
1374 | subtree->it= NULL((void*)0);
1375 | ptvc->pushed_tree_index++;
1376 | return ptvcursor_set_subtree(ptvc, it, ett_subtree);
1377 | }
1378 |
1379 | /* pops a subtree */
1380 | void
1381 | ptvcursor_pop_subtree(ptvcursor_t *ptvc)
1382 | {
1383 | subtree_lvl *subtree;
1384 |
1385 | if (ptvc->pushed_tree_index <= 0)
1386 | return;
1387 |
1388 | ptvc->pushed_tree_index--;
1389 | subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1390 | if (subtree->it != NULL((void*)0))
1391 | proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
1392 |
1393 | ptvc->tree = subtree->tree;
1394 | }
1395 |
1396 | /* saves the current tvb offset and the item in the current subtree level */
1397 | static void
1398 | ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
1399 | {
1400 | subtree_lvl *subtree;
1401 |
1402 | 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", 1402, "ptvc->pushed_tree_index > 0" ))));
1403 |
1404 | subtree = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
1405 | subtree->it = it;
1406 | subtree->cursor_offset = ptvcursor_current_offset(ptvc);
1407 | }
1408 |
1409 | /* Creates a subtree and adds it to the cursor as the working tree but does not
1410 | * save the old working tree */
1411 | proto_tree *
1412 | ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1413 | {
1414 | ptvc->tree = proto_item_add_subtree(it, ett_subtree);
1415 | return ptvc->tree;
1416 | }
1417 |
1418 | static proto_tree *
1419 | ptvcursor_add_subtree_item(ptvcursor_t *ptvc, proto_item *it, int ett_subtree, int length)
1420 | {
1421 | ptvcursor_push_subtree(ptvc, it, ett_subtree);
1422 | if (length == SUBTREE_UNDEFINED_LENGTH-1)
1423 | ptvcursor_subtree_set_item(ptvc, it);
1424 | return ptvcursor_tree(ptvc);
1425 | }
1426 |
1427 | /* Add an item to the tree and create a subtree
1428 | * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1429 | * In this case, when the subtree will be closed, the parent item length will
1430 | * be equal to the advancement of the cursor since the creation of the subtree.
1431 | */
1432 | proto_tree *
1433 | ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, int length,
1434 | const unsigned encoding, int ett_subtree)
1435 | {
1436 | proto_item *it;
1437 |
1438 | it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
1439 | return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
1440 | }
1441 |
1442 | static proto_item *
1443 | proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, int start, int length);
1444 |
1445 | /* Add a text node to the tree and create a subtree
1446 | * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1447 | * In this case, when the subtree will be closed, the item length will be equal
1448 | * to the advancement of the cursor since the creation of the subtree.
1449 | */
1450 | proto_tree *
1451 | ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, int length,
1452 | int ett_subtree, const char *format, ...)
1453 | {
1454 | proto_item *pi;
1455 | va_list ap;
1456 | header_field_info *hfinfo;
1457 | proto_tree *tree;
1458 |
1459 | tree = ptvcursor_tree(ptvc);
1460 |
1461 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1462 |
1463 | 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", 1463 , __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", 1463, "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", 1463, "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", 1463, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
1464 |
1465 | pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
1466 | ptvcursor_current_offset(ptvc), length);
1467 |
1468 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 1468, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
1469 |
1470 | va_start(ap, format)__builtin_va_start(ap, format);
1471 | proto_tree_set_representation(pi, format, ap);
1472 | va_end(ap)__builtin_va_end(ap);
1473 |
1474 | return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
1475 | }
1476 |
1477 | /* Add a text-only node, leaving it to our caller to fill the text in */
1478 | static proto_item *
1479 | proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1480 | {
1481 | proto_item *pi;
1482 |
1483 | if (tree == NULL((void*)0))
1484 | return NULL((void*)0);
1485 |
1486 | pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
1487 |
1488 | return pi;
1489 | }
1490 |
1491 | /* (INTERNAL USE ONLY) Add a text-only node to the proto_tree */
1492 | proto_item *
1493 | proto_tree_add_text_internal(proto_tree *tree, tvbuff_t *tvb, int start, int length,
1494 | const char *format, ...)
1495 | {
1496 | proto_item *pi;
1497 | va_list ap;
1498 | header_field_info *hfinfo;
1499 |
1500 | if (length == -1) {
1501 | length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
1502 | } else {
1503 | tvb_ensure_bytes_exist(tvb, start, length);
1504 | }
1505 |
1506 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1507 |
1508 | 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", 1508 , __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", 1508, "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", 1508, "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", 1508, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
1509 |
1510 | pi = proto_tree_add_text_node(tree, tvb, start, length);
1511 |
1512 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 1512, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
1513 |
1514 | va_start(ap, format)__builtin_va_start(ap, format);
1515 | proto_tree_set_representation(pi, format, ap);
1516 | va_end(ap)__builtin_va_end(ap);
1517 |
1518 | return pi;
1519 | }
1520 |
1521 | /* (INTERNAL USE ONLY) Add a text-only node to the proto_tree (va_list version) */
1522 | proto_item *
1523 | proto_tree_add_text_valist_internal(proto_tree *tree, tvbuff_t *tvb, int start,
1524 | int length, const char *format, va_list ap)
1525 | {
1526 | proto_item *pi;
1527 | header_field_info *hfinfo;
1528 |
1529 | /* proto_tree_add_text_node calls proto_tree_add_pi() with the
1530 | * FT_NONE hf_text_only, which calls get_hfi_length, which adjusts
1531 | * the length to be what's in the tvbuff if length is -1, and the
1532 | * minimum of length and what's in the tvbuff if not.
1533 | */
1534 |
1535 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1536 |
1537 | 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", 1537 , __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", 1537, "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", 1537, "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", 1537, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
1538 |
1539 | pi = proto_tree_add_text_node(tree, tvb, start, length);
1540 |
1541 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 1541, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
1542 |
1543 | proto_tree_set_representation(pi, format, ap);
1544 |
1545 | return pi;
1546 | }
1547 |
1548 | /* Add a text-only node that creates a subtree underneath.
1549 | */
1550 | proto_tree *
1551 | proto_tree_add_subtree(proto_tree *tree, tvbuff_t *tvb, int start, int length, int idx, proto_item **tree_item, const char *text)
1552 | {
1553 | return proto_tree_add_subtree_format(tree, tvb, start, length, idx, tree_item, "%s", text);
1554 | }
1555 |
1556 | /* Add a text-only node that creates a subtree underneath.
1557 | */
1558 | proto_tree *
1559 | proto_tree_add_subtree_format(proto_tree *tree, tvbuff_t *tvb, int start, int length, int idx, proto_item **tree_item, const char *format, ...)
1560 | {
1561 | proto_tree *pt;
1562 | proto_item *pi;
1563 | va_list ap;
1564 |
1565 | va_start(ap, format)__builtin_va_start(ap, format);
1566 | pi = proto_tree_add_text_valist_internal(tree, tvb, start, length, format, ap);
1567 | va_end(ap)__builtin_va_end(ap);
1568 |
1569 | if (tree_item != NULL((void*)0))
1570 | *tree_item = pi;
1571 |
1572 | pt = proto_item_add_subtree(pi, idx);
1573 |
1574 | return pt;
1575 | }
1576 |
1577 | /* Add a text-only node for debugging purposes. The caller doesn't need
1578 | * to worry about tvbuff, start, or length. Debug message gets sent to
1579 | * STDOUT, too */
1580 | proto_item *
1581 | proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
1582 | {
1583 | proto_item *pi;
1584 | va_list ap;
1585 |
1586 | pi = proto_tree_add_text_node(tree, NULL((void*)0), 0, 0);
1587 |
1588 | if (pi) {
1589 | va_start(ap, format)__builtin_va_start(ap, format);
1590 | proto_tree_set_representation(pi, format, ap);
1591 | va_end(ap)__builtin_va_end(ap);
1592 | }
1593 | va_start(ap, format)__builtin_va_start(ap, format);
1594 | vprintf(format, ap);
1595 | va_end(ap)__builtin_va_end(ap);
1596 | printf("\n");
1597 |
1598 | return pi;
1599 | }
1600 |
1601 | proto_item *
1602 | proto_tree_add_format_text(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1603 | {
1604 | proto_item *pi;
1605 | header_field_info *hfinfo;
1606 |
1607 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1608 |
1609 | 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", 1609 , __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", 1609, "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", 1609, "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", 1609, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
1610 |
1611 | pi = proto_tree_add_text_node(tree, tvb, start, length);
1612 |
1613 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 1613, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
1614 |
1615 | proto_item_set_text(pi, "%s", tvb_format_text(tree->tree_data->pinfo->pool, tvb, start, length));
1616 |
1617 | return pi;
1618 | }
1619 |
1620 | proto_item *
1621 | proto_tree_add_format_wsp_text(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1622 | {
1623 | proto_item *pi;
1624 | header_field_info *hfinfo;
1625 | char *str;
1626 |
1627 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1628 |
1629 | 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", 1629 , __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", 1629, "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", 1629, "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", 1629, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
1630 |
1631 | pi = proto_tree_add_text_node(tree, tvb, start, length);
1632 |
1633 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 1633, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
1634 |
1635 | str = tvb_format_text_wsp(NULL((void*)0), tvb, start, length);
1636 | proto_item_set_text(pi, "%s", str);
1637 | wmem_free(NULL((void*)0), str);
1638 |
1639 | return pi;
1640 | }
1641 |
1642 | void proto_report_dissector_bug(const char *format, ...)
1643 | {
1644 | va_list args;
1645 |
1646 | if (wireshark_abort_on_dissector_bug) {
1647 | /*
1648 | * Try to have the error message show up in the crash
1649 | * information.
1650 | */
1651 | va_start(args, format)__builtin_va_start(args, format);
1652 | ws_vadd_crash_info(format, args);
1653 | va_end(args)__builtin_va_end(args);
1654 |
1655 | /*
1656 | * Print the error message.
1657 | */
1658 | va_start(args, format)__builtin_va_start(args, format);
1659 | vfprintf(stderrstderr, format, args);
1660 | va_end(args)__builtin_va_end(args);
1661 | putc('\n', stderrstderr);
1662 |
1663 | /*
1664 | * And crash.
1665 | */
1666 | abort();
1667 | } else {
1668 | va_start(args, format)__builtin_va_start(args, format);
1669 | VTHROW_FORMATTED(DissectorError, format, args)except_vthrowf(1, (6), format, args);
1670 | va_end(args)__builtin_va_end(args);
1671 | ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1671 , __func__, "assertion \"not reached\" failed"); /* GCC 12 with ASAN needs this. */
1672 | }
1673 | }
1674 |
1675 | /* We could probably get away with changing is_error to a minimum length value. */
1676 | static void
1677 | report_type_length_mismatch(proto_tree *tree, const char *descr, int length, bool_Bool is_error)
1678 | {
1679 | if (is_error) {
1680 | expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_error, "Trying to fetch %s with length %d", descr, length);
1681 | } else {
1682 | expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_warn, "Trying to fetch %s with length %d", descr, length);
1683 | }
1684 |
1685 | if (is_error) {
1686 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
1687 | }
1688 | }
1689 |
1690 | static uint32_t
1691 | get_uint_value(proto_tree *tree, tvbuff_t *tvb, int offset, int length, const unsigned encoding)
1692 | {
1693 | uint32_t value;
1694 | bool_Bool length_error;
1695 |
1696 | switch (length) {
1697 |
1698 | case 1:
1699 | value = tvb_get_uint8(tvb, offset);
1700 | if (encoding & ENC_ZIGBEE0x40000000) {
1701 | if (value == 0xFF) { /* Invalid Zigbee length, set to 0 */
1702 | value = 0;
1703 | }
1704 | }
1705 | break;
1706 |
1707 | case 2:
1708 | value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohs(tvb, offset)
1709 | : tvb_get_ntohs(tvb, offset);
1710 | if (encoding & ENC_ZIGBEE0x40000000) {
1711 | if (value == 0xFFFF) { /* Invalid Zigbee length, set to 0 */
1712 | value = 0;
1713 | }
1714 | }
1715 | break;
1716 |
1717 | case 3:
1718 | value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letoh24(tvb, offset)
1719 | : tvb_get_ntoh24(tvb, offset);
1720 | break;
1721 |
1722 | case 4:
1723 | value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1724 | : tvb_get_ntohl(tvb, offset);
1725 | break;
1726 |
1727 | default:
1728 | if (length < 1) {
1729 | length_error = true1;
1730 | value = 0;
1731 | } else {
1732 | length_error = false0;
1733 | value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1734 | : tvb_get_ntohl(tvb, offset);
1735 | }
1736 | report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1737 | break;
1738 | }
1739 | return value;
1740 | }
1741 |
1742 | static inline uint64_t
1743 | get_uint64_value(proto_tree *tree, tvbuff_t *tvb, int offset, unsigned length, const unsigned encoding)
1744 | {
1745 | uint64_t value;
1746 |
1747 | value = tvb_get_uint64_with_length(tvb, offset, length, encoding);
1748 |
1749 | if (length < 1 || length > 8) {
1750 | report_type_length_mismatch(tree, "an unsigned integer", length, (length < 1));
1751 | }
1752 |
1753 | return value;
1754 | }
1755 |
1756 | static int32_t
1757 | get_int_value(proto_tree *tree, tvbuff_t *tvb, int offset, int length, const unsigned encoding)
1758 | {
1759 | int32_t value;
1760 | bool_Bool length_error;
1761 |
1762 | switch (length) {
1763 |
1764 | case 1:
1765 | value = tvb_get_int8(tvb, offset);
1766 | break;
1767 |
1768 | case 2:
1769 | value = encoding ? tvb_get_letohis(tvb, offset)
1770 | : tvb_get_ntohis(tvb, offset);
1771 | break;
1772 |
1773 | case 3:
1774 | value = encoding ? tvb_get_letohi24(tvb, offset)
1775 | : tvb_get_ntohi24(tvb, offset);
1776 | break;
1777 |
1778 | case 4:
1779 | value = encoding ? tvb_get_letohil(tvb, offset)
1780 | : tvb_get_ntohil(tvb, offset);
1781 | break;
1782 |
1783 | default:
1784 | if (length < 1) {
1785 | length_error = true1;
1786 | value = 0;
1787 | } else {
1788 | length_error = false0;
1789 | value = encoding ? tvb_get_letohil(tvb, offset)
1790 | : tvb_get_ntohil(tvb, offset);
1791 | }
1792 | report_type_length_mismatch(tree, "a signed integer", length, length_error);
1793 | break;
1794 | }
1795 | return value;
1796 | }
1797 |
1798 | /* Note: this returns an unsigned int64, but with the appropriate bit(s) set to
1799 | * be cast-able as a int64_t. This is weird, but what the code has always done.
1800 | */
1801 | static inline uint64_t
1802 | get_int64_value(proto_tree *tree, tvbuff_t *tvb, int start, unsigned length, const unsigned encoding)
1803 | {
1804 | uint64_t value = get_uint64_value(tree, tvb, start, length, encoding);
1805 |
1806 | switch (length) {
1807 | case 7:
1808 | value = ws_sign_ext64(value, 56);
1809 | break;
1810 | case 6:
1811 | value = ws_sign_ext64(value, 48);
1812 | break;
1813 | case 5:
1814 | value = ws_sign_ext64(value, 40);
1815 | break;
1816 | case 4:
1817 | value = ws_sign_ext64(value, 32);
1818 | break;
1819 | case 3:
1820 | value = ws_sign_ext64(value, 24);
1821 | break;
1822 | case 2:
1823 | value = ws_sign_ext64(value, 16);
1824 | break;
1825 | case 1:
1826 | value = ws_sign_ext64(value, 8);
1827 | break;
1828 | }
1829 |
1830 | return value;
1831 | }
1832 |
1833 | /* For FT_STRING */
1834 | static inline const uint8_t *
1835 | get_string_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1836 | int length, int *ret_length, const unsigned encoding)
1837 | {
1838 | if (length == -1) {
1839 | length = tvb_ensure_captured_length_remaining(tvb, start);
1840 | }
1841 | *ret_length = length;
1842 | return tvb_get_string_enc(scope, tvb, start, length, encoding);
1843 | }
1844 |
1845 | /* For FT_STRINGZ */
1846 | static inline const uint8_t *
1847 | get_stringz_value(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb,
1848 | int start, int length, int *ret_length, const unsigned encoding)
1849 | {
1850 | const uint8_t *value;
1851 |
1852 | if (length < -1) {
1853 | report_type_length_mismatch(tree, "a string", length, true1);
1854 | }
1855 |
1856 | /* XXX - Ideally, every "null-terminated string which fits into a
1857 | * known length" should be either FT_STRINGZPAD or FT_STRINGZTRUNC
1858 | * as appropriate, not a FT_STRINGZ. If so, then we could always call
1859 | * tvb_get_stringz_enc here. Failing that, we could treat length 0
1860 | * as unknown length as well (since there is a trailing '\0', the real
1861 | * length is never zero), allowing switching to unsigned lengths.
1862 | */
1863 | if (length == -1) {
1864 | /* This can throw an exception */
1865 | value = tvb_get_stringz_enc(scope, tvb, start, (unsigned*)&length, encoding);
1866 | } else {
1867 | /* In this case, length signifies the length of the string.
1868 | *
1869 | * This could either be a null-padded string, which doesn't
1870 | * necessarily have a '\0' at the end, or a null-terminated
1871 | * string, with a trailing '\0'. (Yes, there are cases
1872 | * where you have a string that's both counted and null-
1873 | * terminated.)
1874 | *
1875 | * In the first case, we must allocate a buffer of length
1876 | * "length+1", to make room for a trailing '\0'.
1877 | *
1878 | * In the second case, we don't assume that there is a
1879 | * trailing '\0' there, as the packet might be malformed.
1880 | * (XXX - should we throw an exception if there's no
1881 | * trailing '\0'?) Therefore, we allocate a buffer of
1882 | * length "length+1", and put in a trailing '\0', just to
1883 | * be safe.
1884 | *
1885 | * (XXX - this would change if we made string values counted
1886 | * rather than null-terminated.)
1887 | */
1888 | value = tvb_get_string_enc(scope, tvb, start, length, encoding);
1889 | }
1890 | *ret_length = length;
1891 | return value;
1892 | }
1893 |
1894 | /* For FT_UINT_STRING */
1895 | static inline const uint8_t *
1896 | get_uint_string_value(wmem_allocator_t *scope, proto_tree *tree,
1897 | tvbuff_t *tvb, int start, int length, int *ret_length,
1898 | const unsigned encoding)
1899 | {
1900 | uint32_t n;
1901 | const uint8_t *value;
1902 |
1903 | /* I believe it's ok if this is called with a NULL tree */
1904 | n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
1905 | value = tvb_get_string_enc(scope, tvb, start + length, n, encoding);
1906 | length += n;
1907 | *ret_length = length;
1908 | return value;
1909 | }
1910 |
1911 | /* For FT_STRINGZPAD */
1912 | static inline const uint8_t *
1913 | get_stringzpad_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1914 | int length, int *ret_length, const unsigned encoding)
1915 | {
1916 | /*
1917 | * XXX - currently, string values are null-
1918 | * terminated, so a "zero-padded" string
1919 | * isn't special. If we represent string
1920 | * values as something that includes a counted
1921 | * array of bytes, we'll need to strip the
1922 | * trailing NULs.
1923 | */
1924 | if (length == -1) {
1925 | length = tvb_ensure_captured_length_remaining(tvb, start);
1926 | }
1927 | *ret_length = length;
1928 | return tvb_get_string_enc(scope, tvb, start, length, encoding);
1929 | }
1930 |
1931 | /* For FT_STRINGZTRUNC */
1932 | static inline const uint8_t *
1933 | get_stringztrunc_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1934 | int length, int *ret_length, const unsigned encoding)
1935 | {
1936 | /*
1937 | * XXX - currently, string values are null-
1938 | * terminated, so a "zero-truncated" string
1939 | * isn't special. If we represent string
1940 | * values as something that includes a counted
1941 | * array of bytes, we'll need to strip everything
1942 | * starting with the terminating NUL.
1943 | */
1944 | if (length == -1) {
1945 | length = tvb_ensure_captured_length_remaining(tvb, start);
1946 | }
1947 | *ret_length = length;
1948 | return tvb_get_string_enc(scope, tvb, start, length, encoding);
1949 | }
1950 |
1951 | /*
1952 | * Deltas between the epochs for various non-UN*X time stamp formats and
1953 | * the January 1, 1970, 00:00:00 (proleptic?) UTC epoch for the UN*X time
1954 | * stamp format.
1955 | */
1956 |
1957 | /*
1958 | * NTP Era 0: the epoch is January 1, 1900, 00:00:00 (proleptic?) UTC.
1959 | * XXX - if it's OK if this is unsigned, can we just use
1960 | * EPOCH_DELTA_1900_01_01_00_00_00_UTC?
1961 | */
1962 | #define NTP_TIMEDIFF1900TO1970SEC2208988800L INT64_C(2208988800)2208988800L
1963 |
1964 | /*
1965 | * NTP Era 1: the epoch is February 7, 2036, 06:28:16 UTC.
1966 | */
1967 | #define NTP_TIMEDIFF1970TO2036SEC2085978496L INT64_C(2085978496)2085978496L
1968 |
1969 | /* this can be called when there is no tree, so tree may be null */
1970 | static void
1971 | get_time_value(proto_tree *tree, tvbuff_t *tvb, const int start,
1972 | const int length, const unsigned encoding, nstime_t *time_stamp,
1973 | const bool_Bool is_relative)
1974 | {
1975 | uint32_t tmpsecs;
1976 | uint64_t tmp64secs;
1977 | uint64_t todusecs;
1978 |
1979 | switch (encoding) {
1980 |
1981 | case ENC_TIME_SECS_NSECS0x00000000|ENC_BIG_ENDIAN0x00000000:
1982 | /*
1983 | * If the length is 16, 8-byte seconds, followed
1984 | * by 8-byte fractional time in nanoseconds,
1985 | * both big-endian.
1986 | *
1987 | * If the length is 12, 8-byte seconds, followed
1988 | * by 4-byte fractional time in nanoseconds,
1989 | * both big-endian.
1990 | *
1991 | * If the length is 8, 4-byte seconds, followed
1992 | * by 4-byte fractional time in nanoseconds,
1993 | * both big-endian.
1994 | *
1995 | * For absolute times, the seconds are seconds
1996 | * since the UN*X epoch.
1997 | */
1998 | if (length == 16) {
1999 | time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2000 | time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8);
2001 | } else if (length == 12) {
2002 | time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2003 | time_stamp->nsecs = tvb_get_ntohl(tvb, start+8);
2004 | } else if (length == 8) {
2005 | time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2006 | time_stamp->nsecs = tvb_get_ntohl(tvb, start+4);
2007 | } else if (length == 4) {
2008 | /*
2009 | * Backwards compatibility.
2010 | * ENC_TIME_SECS_NSECS is 0; using
2011 | * ENC_BIG_ENDIAN by itself with a 4-byte
2012 | * time-in-seconds value was done in the
2013 | * past.
2014 | */
2015 | time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2016 | time_stamp->nsecs = 0;
2017 | } else {
2018 | time_stamp->secs = 0;
2019 | time_stamp->nsecs = 0;
2020 | report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2021 | }
2022 | break;
2023 |
2024 | case ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000:
2025 | /*
2026 | * If the length is 16, 8-byte seconds, followed
2027 | * by 8-byte fractional time in nanoseconds,
2028 | * both little-endian.
2029 | *
2030 | * If the length is 12, 8-byte seconds, followed
2031 | * by 4-byte fractional time in nanoseconds,
2032 | * both little-endian.
2033 | *
2034 | * If the length is 8, 4-byte seconds, followed
2035 | * by 4-byte fractional time in nanoseconds,
2036 | * both little-endian.
2037 | *
2038 | * For absolute times, the seconds are seconds
2039 | * since the UN*X epoch.
2040 | */
2041 | if (length == 16) {
2042 | time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2043 | time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8);
2044 | } else if (length == 12) {
2045 | time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2046 | time_stamp->nsecs = tvb_get_letohl(tvb, start+8);
2047 | } else if (length == 8) {
2048 | time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2049 | time_stamp->nsecs = tvb_get_letohl(tvb, start+4);
2050 | } else if (length == 4) {
2051 | /*
2052 | * Backwards compatibility.
2053 | * ENC_TIME_SECS_NSECS is 0; using
2054 | * ENC_LITTLE_ENDIAN by itself with a 4-byte
2055 | * time-in-seconds value was done in the
2056 | * past.
2057 | */
2058 | time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2059 | time_stamp->nsecs = 0;
2060 | } else {
2061 | time_stamp->secs = 0;
2062 | time_stamp->nsecs = 0;
2063 | report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2064 | }
2065 | break;
2066 |
2067 | case ENC_TIME_NTP0x00000002|ENC_BIG_ENDIAN0x00000000:
2068 | /*
2069 | * NTP time stamp, big-endian.
2070 | * Only supported for absolute times.
2071 | */
2072 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2072, "!is_relative" ))));
2073 |
2074 | /* We need a temporary variable here so the unsigned math
2075 | * works correctly (for years > 2036 according to RFC 2030
2076 | * chapter 3).
2077 | *
2078 | * If bit 0 is set, the UTC time is in the range 1968-2036 and
2079 | * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2080 | * If bit 0 is not set, the time is in the range 2036-2104 and
2081 | * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2082 | */
2083 | tmpsecs = tvb_get_ntohl(tvb, start);
2084 | if ((tmpsecs & 0x80000000) != 0)
2085 | time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2086 | else
2087 | time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2088 |
2089 | if (length == 8) {
2090 | tmp64secs = tvb_get_ntoh64(tvb, start);
2091 | if (tmp64secs == 0) {
2092 | //This is "NULL" time
2093 | time_stamp->secs = 0;
2094 | time_stamp->nsecs = 0;
2095 | } else {
2096 | /*
2097 | * Convert 1/2^32s of a second to
2098 | * nanoseconds.
2099 | */
2100 | time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2101 | }
2102 | } else if (length == 4) {
2103 | /*
2104 | * Backwards compatibility.
2105 | */
2106 | if (tmpsecs == 0) {
2107 | //This is "NULL" time
2108 | time_stamp->secs = 0;
2109 | }
2110 | time_stamp->nsecs = 0;
2111 | } else {
2112 | time_stamp->secs = 0;
2113 | time_stamp->nsecs = 0;
2114 | report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2115 | }
2116 | break;
2117 |
2118 | case ENC_TIME_NTP0x00000002|ENC_LITTLE_ENDIAN0x80000000:
2119 | /*
2120 | * NTP time stamp, little-endian.
2121 | * Only supported for absolute times.
2122 | *
2123 | * NTP doesn't use this, because it's an Internet format
2124 | * and hence big-endian. Any implementation must decide
2125 | * whether the NTP timestamp is a 64-bit unsigned fixed
2126 | * point number (RFC 1305, RFC 4330) or a 64-bit struct
2127 | * with a 32-bit unsigned seconds field followed by a
2128 | * 32-bit fraction field (cf. RFC 5905, which obsoletes
2129 | * the previous two).
2130 | *
2131 | * XXX: We do the latter, but no dissector uses this format.
2132 | * OTOH, ERF timestamps do the former, so perhaps we
2133 | * should switch the interpretation so that packet-erf.c
2134 | * could use this directly?
2135 | */
2136 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2136, "!is_relative" ))));
2137 |
2138 | /* We need a temporary variable here so the unsigned math
2139 | * works correctly (for years > 2036 according to RFC 2030
2140 | * chapter 3).
2141 | *
2142 | * If bit 0 is set, the UTC time is in the range 1968-2036 and
2143 | * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2144 | * If bit 0 is not set, the time is in the range 2036-2104 and
2145 | * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2146 | */
2147 | tmpsecs = tvb_get_letohl(tvb, start);
2148 | if ((tmpsecs & 0x80000000) != 0)
2149 | time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2150 | else
2151 | time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2152 |
2153 | if (length == 8) {
2154 | tmp64secs = tvb_get_letoh64(tvb, start);
2155 | if (tmp64secs == 0) {
2156 | //This is "NULL" time
2157 | time_stamp->secs = 0;
2158 | time_stamp->nsecs = 0;
2159 | } else {
2160 | /*
2161 | * Convert 1/2^32s of a second to
2162 | * nanoseconds.
2163 | */
2164 | time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2165 | }
2166 | } else if (length == 4) {
2167 | /*
2168 | * Backwards compatibility.
2169 | */
2170 | if (tmpsecs == 0) {
2171 | //This is "NULL" time
2172 | time_stamp->secs = 0;
2173 | }
2174 | time_stamp->nsecs = 0;
2175 | } else {
2176 | time_stamp->secs = 0;
2177 | time_stamp->nsecs = 0;
2178 | report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2179 | }
2180 | break;
2181 |
2182 | case ENC_TIME_TOD0x00000004|ENC_BIG_ENDIAN0x00000000:
2183 | /*
2184 | * S/3x0 and z/Architecture TOD clock time stamp,
2185 | * big-endian. The epoch is January 1, 1900,
2186 | * 00:00:00 (proleptic?) UTC.
2187 | *
2188 | * Only supported for absolute times.
2189 | */
2190 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2190, "!is_relative" ))));
2191 | DISSECTOR_ASSERT(length == 8)((void) ((length == 8) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2191, "length == 8" ))));
2192 |
2193 | if (length == 8) {
2194 | todusecs = tvb_get_ntoh64(tvb, start) >> 12;
2195 | time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2196 | time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2197 | } else {
2198 | time_stamp->secs = 0;
2199 | time_stamp->nsecs = 0;
2200 | report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2201 | }
2202 | break;
2203 |
2204 | case ENC_TIME_TOD0x00000004|ENC_LITTLE_ENDIAN0x80000000:
2205 | /*
2206 | * S/3x0 and z/Architecture TOD clock time stamp,
2207 | * little-endian. The epoch is January 1, 1900,
2208 | * 00:00:00 (proleptic?) UTC.
2209 | *
2210 | * Only supported for absolute times.
2211 | */
2212 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2212, "!is_relative" ))));
2213 |
2214 | if (length == 8) {
2215 | todusecs = tvb_get_letoh64(tvb, start) >> 12 ;
2216 | time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2217 | time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2218 | } else {
2219 | time_stamp->secs = 0;
2220 | time_stamp->nsecs = 0;
2221 | report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2222 | }
2223 | break;
2224 |
2225 | case ENC_TIME_RTPS0x00000008|ENC_BIG_ENDIAN0x00000000:
2226 | /*
2227 | * Time stamp using the same seconds/fraction format
2228 | * as NTP, but with the origin of the time stamp being
2229 | * the UNIX epoch rather than the NTP epoch; big-
2230 | * endian.
2231 | *
2232 | * Only supported for absolute times.
2233 | */
2234 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2234, "!is_relative" ))));
2235 |
2236 | if (length == 8) {
2237 | time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2238 | /*
2239 | * Convert 1/2^32s of a second to nanoseconds.
2240 | */
2241 | time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2242 | } else {
2243 | time_stamp->secs = 0;
2244 | time_stamp->nsecs = 0;
2245 | report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2246 | }
2247 | break;
2248 |
2249 | case ENC_TIME_RTPS0x00000008|ENC_LITTLE_ENDIAN0x80000000:
2250 | /*
2251 | * Time stamp using the same seconds/fraction format
2252 | * as NTP, but with the origin of the time stamp being
2253 | * the UNIX epoch rather than the NTP epoch; little-
2254 | * endian.
2255 | *
2256 | * Only supported for absolute times.
2257 | *
2258 | * The RTPS specification explicitly supports Little
2259 | * Endian encoding. In one place, it states that its
2260 | * Time_t representation "is the one defined by ...
2261 | * RFC 1305", but in another explicitly defines it as
2262 | * a struct consisting of an 32 bit unsigned seconds
2263 | * field and a 32 bit unsigned fraction field, not a 64
2264 | * bit fixed point, so we do that here.
2265 | * https://www.omg.org/spec/DDSI-RTPS/2.5/PDF
2266 | */
2267 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2267, "!is_relative" ))));
2268 |
2269 | if (length == 8) {
2270 | time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2271 | /*
2272 | * Convert 1/2^32s of a second to nanoseconds.
2273 | */
2274 | time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2275 | } else {
2276 | time_stamp->secs = 0;
2277 | time_stamp->nsecs = 0;
2278 | report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2279 | }
2280 | break;
2281 |
2282 | case ENC_TIME_MIP60x00000024 | ENC_BIG_ENDIAN0x00000000:
2283 | /*
2284 | * MIP6 time stamp, big-endian.
2285 | * A 64-bit unsigned integer field containing a timestamp. The
2286 | * value indicates the number of seconds since January 1, 1970,
2287 | * 00:00 UTC, by using a fixed point format. In this format, the
2288 | * integer number of seconds is contained in the first 48 bits of
2289 | * the field, and the remaining 16 bits indicate the number of
2290 | * 1/65536 fractions of a second.
2291 |
2292 | * Only supported for absolute times.
2293 | */
2294 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2294, "!is_relative" ))));
2295 |
2296 | if (length == 8) {
2297 | /* We need a temporary variable here so the casting and fractions
2298 | * of a second work correctly.
2299 | */
2300 | tmp64secs = tvb_get_ntoh48(tvb, start);
2301 | tmpsecs = tvb_get_ntohs(tvb, start + 6);
2302 | tmpsecs <<= 16;
2303 |
2304 | if ((tmp64secs == 0) && (tmpsecs == 0)) {
2305 | //This is "NULL" time
2306 | time_stamp->secs = 0;
2307 | time_stamp->nsecs = 0;
2308 | } else {
2309 | time_stamp->secs = (time_t)tmp64secs;
2310 | time_stamp->nsecs = (int)((tmpsecs / 4294967296.0) * 1000000000);
2311 | }
2312 | } else {
2313 | time_stamp->secs = 0;
2314 | time_stamp->nsecs = 0;
2315 | report_type_length_mismatch(tree, "an NTP time stamp", length, (length != 8));
2316 | }
2317 | break;
2318 |
2319 | case ENC_TIME_SECS_USECS0x00000010|ENC_BIG_ENDIAN0x00000000:
2320 | /*
2321 | * If the length is 16, 8-byte seconds, followed
2322 | * by 8-byte fractional time in microseconds,
2323 | * both big-endian.
2324 | *
2325 | * If the length is 12, 8-byte seconds, followed
2326 | * by 4-byte fractional time in microseconds,
2327 | * both big-endian.
2328 | *
2329 | * If the length is 8, 4-byte seconds, followed
2330 | * by 4-byte fractional time in microseconds,
2331 | * both big-endian.
2332 | *
2333 | * For absolute times, the seconds are seconds
2334 | * since the UN*X epoch.
2335 | */
2336 | if (length == 16) {
2337 | time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2338 | time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8)*1000;
2339 | } else if (length == 12) {
2340 | time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2341 | time_stamp->nsecs = tvb_get_ntohl(tvb, start+8)*1000;
2342 | } else if (length == 8) {
2343 | time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2344 | time_stamp->nsecs = tvb_get_ntohl(tvb, start+4)*1000;
2345 | } else {
2346 | time_stamp->secs = 0;
2347 | time_stamp->nsecs = 0;
2348 | report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2349 | }
2350 | break;
2351 |
2352 | case ENC_TIME_SECS_USECS0x00000010|ENC_LITTLE_ENDIAN0x80000000:
2353 | /*
2354 | * If the length is 16, 8-byte seconds, followed
2355 | * by 8-byte fractional time in microseconds,
2356 | * both little-endian.
2357 | *
2358 | * If the length is 12, 8-byte seconds, followed
2359 | * by 4-byte fractional time in microseconds,
2360 | * both little-endian.
2361 | *
2362 | * If the length is 8, 4-byte seconds, followed
2363 | * by 4-byte fractional time in microseconds,
2364 | * both little-endian.
2365 | *
2366 | * For absolute times, the seconds are seconds
2367 | * since the UN*X epoch.
2368 | */
2369 | if (length == 16) {
2370 | time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2371 | time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8)*1000;
2372 | } else if (length == 12) {
2373 | time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2374 | time_stamp->nsecs = tvb_get_letohl(tvb, start+8)*1000;
2375 | } else if (length == 8) {
2376 | time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2377 | time_stamp->nsecs = tvb_get_letohl(tvb, start+4)*1000;
2378 | } else {
2379 | time_stamp->secs = 0;
2380 | time_stamp->nsecs = 0;
2381 | report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2382 | }
2383 | break;
2384 |
2385 | case ENC_TIME_SECS0x00000012|ENC_BIG_ENDIAN0x00000000:
2386 | case ENC_TIME_SECS0x00000012|ENC_LITTLE_ENDIAN0x80000000:
2387 | /*
2388 | * Seconds, 1 to 8 bytes.
2389 | * For absolute times, it's seconds since the
2390 | * UN*X epoch.
2391 | */
2392 | if (length >= 1 && length <= 8) {
2393 | time_stamp->secs = (time_t)get_uint64_value(tree, tvb, start, length, encoding);
2394 | time_stamp->nsecs = 0;
2395 | } else {
2396 | time_stamp->secs = 0;
2397 | time_stamp->nsecs = 0;
2398 | report_type_length_mismatch(tree, "a time-in-seconds time stamp", length, (length < 4));
2399 | }
2400 | break;
2401 |
2402 | case ENC_TIME_MSECS0x00000014|ENC_BIG_ENDIAN0x00000000:
2403 | case ENC_TIME_MSECS0x00000014|ENC_LITTLE_ENDIAN0x80000000:
2404 | /*
2405 | * Milliseconds, 1 to 8 bytes.
2406 | * For absolute times, it's milliseconds since the
2407 | * UN*X epoch.
2408 | */
2409 | if (length >= 1 && length <= 8) {
2410 | uint64_t msecs;
2411 |
2412 | msecs = get_uint64_value(tree, tvb, start, length, encoding);
2413 | time_stamp->secs = (time_t)(msecs / 1000);
2414 | time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2415 | } else {
2416 | time_stamp->secs = 0;
2417 | time_stamp->nsecs = 0;
2418 | report_type_length_mismatch(tree, "a time-in-milliseconds time stamp", length, (length < 4));
2419 | }
2420 | break;
2421 |
2422 | case ENC_TIME_USECS0x00000030|ENC_BIG_ENDIAN0x00000000:
2423 | case ENC_TIME_USECS0x00000030|ENC_LITTLE_ENDIAN0x80000000:
2424 | /*
2425 | * Microseconds, 1 to 8 bytes.
2426 | * For absolute times, it's microseconds since the
2427 | * UN*X epoch.
2428 | */
2429 | if (length >= 1 && length <= 8) {
2430 | uint64_t usecs;
2431 |
2432 | usecs = get_uint64_value(tree, tvb, start, length, encoding);
2433 | time_stamp->secs = (time_t)(usecs / 1000000);
2434 | time_stamp->nsecs = (int)(usecs % 1000000)*1000;
2435 | } else {
2436 | time_stamp->secs = 0;
2437 | time_stamp->nsecs = 0;
2438 | report_type_length_mismatch(tree, "a time-in-microseconds time stamp", length, (length < 4));
2439 | }
2440 | break;
2441 |
2442 | case ENC_TIME_NSECS0x00000028|ENC_BIG_ENDIAN0x00000000:
2443 | case ENC_TIME_NSECS0x00000028|ENC_LITTLE_ENDIAN0x80000000:
2444 | /*
2445 | * nanoseconds, 1 to 8 bytes.
2446 | * For absolute times, it's nanoseconds since the
2447 | * UN*X epoch.
2448 | */
2449 |
2450 | if (length >= 1 && length <= 8) {
2451 | uint64_t nsecs;
2452 |
2453 | nsecs = get_uint64_value(tree, tvb, start, length, encoding);
2454 | time_stamp->secs = (time_t)(nsecs / 1000000000);
2455 | time_stamp->nsecs = (int)(nsecs % 1000000000);
2456 | } else {
2457 | time_stamp->secs = 0;
2458 | time_stamp->nsecs = 0;
2459 | report_type_length_mismatch(tree, "a time-in-nanoseconds time stamp", length, (length < 4));
2460 | }
2461 | break;
2462 |
2463 | case ENC_TIME_RFC_39710x00000020|ENC_BIG_ENDIAN0x00000000:
2464 | /*
2465 | * 1/64ths of a second since the UN*X epoch,
2466 | * big-endian.
2467 | *
2468 | * Only supported for absolute times.
2469 | */
2470 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2470, "!is_relative" ))));
2471 |
2472 | if (length == 8) {
2473 | /*
2474 | * The upper 48 bits are seconds since the
2475 | * UN*X epoch.
2476 | */
2477 | time_stamp->secs = (time_t)tvb_get_ntoh48(tvb, start);
2478 | /*
2479 | * The lower 16 bits are 1/2^16s of a second;
2480 | * convert them to nanoseconds.
2481 | *
2482 | * XXX - this may give the impression of higher
2483 | * precision than you actually get.
2484 | */
2485 | time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohs(tvb, start+6)/65536.0));
2486 | } else {
2487 | time_stamp->secs = 0;
2488 | time_stamp->nsecs = 0;
2489 | report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2490 | }
2491 | break;
2492 |
2493 | case ENC_TIME_RFC_39710x00000020|ENC_LITTLE_ENDIAN0x80000000:
2494 | /*
2495 | * 1/64ths of a second since the UN*X epoch,
2496 | * little-endian.
2497 | *
2498 | * Only supported for absolute times.
2499 | */
2500 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2500, "!is_relative" ))));
2501 |
2502 | if (length == 8) {
2503 | /*
2504 | * XXX - this is assuming that, if anybody
2505 | * were ever to use this format - RFC 3971
2506 | * doesn't, because that's an Internet
2507 | * protocol, and those use network byte
2508 | * order, i.e. big-endian - they'd treat it
2509 | * as a 64-bit count of 1/2^16s of a second,
2510 | * putting the upper 48 bits at the end.
2511 | *
2512 | * The lower 48 bits are seconds since the
2513 | * UN*X epoch.
2514 | */
2515 | time_stamp->secs = (time_t)tvb_get_letoh48(tvb, start+2);
2516 | /*
2517 | * The upper 16 bits are 1/2^16s of a second;
2518 | * convert them to nanoseconds.
2519 | *
2520 | * XXX - this may give the impression of higher
2521 | * precision than you actually get.
2522 | */
2523 | time_stamp->nsecs = (int)(1000000000*(tvb_get_letohs(tvb, start)/65536.0));
2524 | } else {
2525 | time_stamp->secs = 0;
2526 | time_stamp->nsecs = 0;
2527 | report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2528 | }
2529 | break;
2530 |
2531 | case ENC_TIME_SECS_NTP0x00000018|ENC_BIG_ENDIAN0x00000000:
2532 | /*
2533 | * NTP time stamp, with 1-second resolution (i.e.,
2534 | * seconds since the NTP epoch), big-endian.
2535 | * Only supported for absolute times.
2536 | */
2537 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2537, "!is_relative" ))));
2538 |
2539 | if (length == 4) {
2540 | /*
2541 | * We need a temporary variable here so the unsigned math
2542 | * works correctly (for years > 2036 according to RFC 2030
2543 | * chapter 3).
2544 | *
2545 | * If bit 0 is set, the UTC time is in the range 1968-2036 and
2546 | * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2547 | * If bit 0 is not set, the time is in the range 2036-2104 and
2548 | * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2549 | */
2550 | tmpsecs = tvb_get_ntohl(tvb, start);
2551 | if ((tmpsecs & 0x80000000) != 0)
2552 | time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2553 | else
2554 | time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2555 | time_stamp->nsecs = 0;
2556 | } else {
2557 | time_stamp->secs = 0;
2558 | time_stamp->nsecs = 0;
2559 | report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2560 | }
2561 | break;
2562 |
2563 | case ENC_TIME_SECS_NTP0x00000018|ENC_LITTLE_ENDIAN0x80000000:
2564 | /*
2565 | * NTP time stamp, with 1-second resolution (i.e.,
2566 | * seconds since the NTP epoch), little-endian.
2567 | * Only supported for absolute times.
2568 | */
2569 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2569, "!is_relative" ))));
2570 |
2571 | /*
2572 | * We need a temporary variable here so the unsigned math
2573 | * works correctly (for years > 2036 according to RFC 2030
2574 | * chapter 3).
2575 | *
2576 | * If bit 0 is set, the UTC time is in the range 1968-2036 and
2577 | * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2578 | * If bit 0 is not set, the time is in the range 2036-2104 and
2579 | * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2580 | */
2581 | if (length == 4) {
2582 | tmpsecs = tvb_get_letohl(tvb, start);
2583 | if ((tmpsecs & 0x80000000) != 0)
2584 | time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2585 | else
2586 | time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2587 | time_stamp->nsecs = 0;
2588 | } else {
2589 | time_stamp->secs = 0;
2590 | time_stamp->nsecs = 0;
2591 | report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2592 | }
2593 | break;
2594 |
2595 | case ENC_TIME_MSEC_NTP0x00000022 | ENC_BIG_ENDIAN0x00000000:
2596 | /*
2597 | * Milliseconds, 6 to 8 bytes.
2598 | * For absolute times, it's milliseconds since the
2599 | * NTP epoch.
2600 | *
2601 | * ETSI TS 129.274 8.119 defines this as:
2602 | * "a 48 bit unsigned integer in network order format
2603 | * ...encoded as the number of milliseconds since
2604 | * 00:00:00 January 1, 1900 00:00 UTC, i.e. as the
2605 | * rounded value of 1000 x the value of the 64-bit
2606 | * timestamp (Seconds + (Fraction / (1<<32))) defined
2607 | * in clause 6 of IETF RFC 5905."
2608 | *
2609 | * Taken literally, the part after "i.e." would
2610 | * mean that the value rolls over before reaching
2611 | * 2^32 * 1000 = 4294967296000 = 0x3e800000000
2612 | * when the 64 bit timestamp rolls over, and we have
2613 | * to pick an NTP Era equivalence class to support
2614 | * (such as 1968-01-20 to 2104-02-06).
2615 | *
2616 | * OTOH, the extra room might be used to store Era
2617 | * information instead, in which case times until
2618 | * 10819-08-03 can be represented with 6 bytes without
2619 | * ambiguity. We handle both implementations, and assume
2620 | * that times before 1968-01-20 are not represented.
2621 | *
2622 | * Only 6 bytes or more makes sense as an absolute
2623 | * time. 5 bytes or fewer could express a span of
2624 | * less than 35 years, either 1900-1934 or 2036-2070.
2625 | */
2626 | if (length >= 6 && length <= 8) {
2627 | uint64_t msecs;
2628 |
2629 | msecs = get_uint64_value(tree, tvb, start, length, encoding);
2630 | tmp64secs = (msecs / 1000);
2631 | /*
2632 | * Assume that times in the first half of NTP
2633 | * Era 0 really represent times in the NTP
2634 | * Era 1.
2635 | */
2636 | if (tmp64secs >= 0x80000000)
2637 | time_stamp->secs = (time_t)((int64_t)tmp64secs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2638 | else
2639 | time_stamp->secs = (time_t)((int64_t)tmp64secs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2640 | time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2641 | }
2642 | else {
2643 | time_stamp->secs = 0;
2644 | time_stamp->nsecs = 0;
2645 | report_type_length_mismatch(tree, "a time-in-milliseconds NTP time stamp", length, (length < 6));
2646 | }
2647 | break;
2648 |
2649 | case ENC_TIME_MP4_FILE_SECS0x00000026|ENC_BIG_ENDIAN0x00000000:
2650 | /*
2651 | * MP4 file time stamps, big-endian.
2652 | * Only supported for absolute times.
2653 | */
2654 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2654, "!is_relative" ))));
2655 |
2656 | if (length == 8) {
2657 | tmp64secs = tvb_get_ntoh64(tvb, start);
2658 | time_stamp->secs = (time_t)(int64_t)(tmp64secs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2659 | time_stamp->nsecs = 0;
2660 | } else if (length == 4) {
2661 | tmpsecs = tvb_get_ntohl(tvb, start);
2662 | time_stamp->secs = (time_t)(int32_t)(tmpsecs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2663 | time_stamp->nsecs = 0;
2664 | } else {
2665 | time_stamp->secs = 0;
2666 | time_stamp->nsecs = 0;
2667 | report_type_length_mismatch(tree, "an MP4 time stamp", length, (length < 4));
2668 | }
2669 | break;
2670 |
2671 | case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_BIG_ENDIAN0x00000000:
2672 | /*
2673 | * Zigbee ZCL time stamps, big-endian.
2674 | * Only supported for absolute times.
2675 | */
2676 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2676, "!is_relative" ))));
2677 |
2678 | if (length == 8) {
2679 | tmp64secs = tvb_get_ntoh64(tvb, start);
2680 | 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);
2681 | time_stamp->nsecs = 0;
2682 | } else if (length == 4) {
2683 | tmpsecs = tvb_get_ntohl(tvb, start);
2684 | time_stamp->secs = (time_t)(tmpsecs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2685 | time_stamp->nsecs = 0;
2686 | } else {
2687 | time_stamp->secs = 0;
2688 | time_stamp->nsecs = 0;
2689 | report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2690 | }
2691 | break;
2692 |
2693 | case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_LITTLE_ENDIAN0x80000000:
2694 | /*
2695 | * Zigbee ZCL time stamps, little-endian.
2696 | * Only supported for absolute times.
2697 | */
2698 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2698, "!is_relative" ))));
2699 |
2700 | if (length == 8) {
2701 | tmp64secs = tvb_get_letoh64(tvb, start);
2702 | 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);
2703 | time_stamp->nsecs = 0;
2704 | } else if (length == 4) {
2705 | tmpsecs = tvb_get_letohl(tvb, start);
2706 | time_stamp->secs = (time_t)(tmpsecs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2707 | time_stamp->nsecs = 0;
2708 | } else {
2709 | time_stamp->secs = 0;
2710 | time_stamp->nsecs = 0;
2711 | report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2712 | }
2713 | break;
2714 |
2715 | default:
2716 | DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\"" , "epan/proto.c", 2716));
2717 | break;
2718 | }
2719 | }
2720 |
2721 | static void
2722 | tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
2723 | {
2724 | const header_field_info *hfinfo = fi->hfinfo;
2725 |
2726 | if (hfinfo->ref_type == HF_REF_TYPE_DIRECT || hfinfo->ref_type == HF_REF_TYPE_PRINT) {
2727 | GPtrArray *ptrs = NULL((void*)0);
2728 |
2729 | if (tree_data->interesting_hfids == NULL((void*)0)) {
2730 | /* Initialize the hash because we now know that it is needed */
2731 | tree_data->interesting_hfids =
2732 | g_hash_table_new(g_direct_hash, NULL((void*)0) /* g_direct_equal */);
2733 | } else if (g_hash_table_size(tree_data->interesting_hfids)) {
2734 | ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
2735 | GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)));
2736 | }
2737 |
2738 | if (!ptrs) {
2739 | /* First element triggers the creation of pointer array */
2740 | ptrs = g_ptr_array_new();
2741 | g_hash_table_insert(tree_data->interesting_hfids,
2742 | GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)), ptrs);
2743 | }
2744 |
2745 | g_ptr_array_add(ptrs, fi);
2746 | }
2747 | }
2748 |
2749 |
2750 | /*
2751 | * Validates that field length bytes are available starting from
2752 | * start (pos/neg). Throws an exception if they aren't.
2753 | */
2754 | static void
2755 | test_length(header_field_info *hfinfo, tvbuff_t *tvb,
2756 | int start, int length, const unsigned encoding)
2757 | {
2758 | int size = length;
2759 |
2760 | if (!tvb)
2761 | return;
2762 |
2763 | if ((hfinfo->type == FT_STRINGZ) ||
2764 | ((encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) &&
2765 | (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 ))))) {
2766 | /* If we're fetching until the end of the TVB, only validate
2767 | * that the offset is within range.
2768 | */
2769 | if (length == -1)
2770 | size = 0;
2771 | }
2772 |
2773 | tvb_ensure_bytes_exist(tvb, start, size);
2774 | }
2775 |
2776 | static void
2777 | detect_trailing_stray_characters(unsigned encoding, const char *string, int length, proto_item *pi)
2778 | {
2779 | bool_Bool found_stray_character = false0;
2780 |
2781 | if (!string)
2782 | return;
2783 |
2784 | switch (encoding & ENC_CHARENCODING_MASK0x0000FFFE) {
2785 | case ENC_ASCII0x00000000:
2786 | case ENC_UTF_80x00000002:
2787 | for (int i = (int)strlen(string); i < length; i++) {
2788 | if (string[i] != '\0') {
2789 | found_stray_character = true1;
2790 | break;
2791 | }
2792 | }
2793 | break;
2794 |
2795 | default:
2796 | break;
2797 | }
2798 |
2799 | if (found_stray_character) {
2800 | expert_add_info(NULL((void*)0), pi, &ei_string_trailing_characters);
2801 | }
2802 | }
2803 |
2804 | static void
2805 | free_fvalue_cb(void *data)
2806 | {
2807 | fvalue_t *fv = (fvalue_t*)data;
2808 | fvalue_free(fv);
2809 | }
2810 |
2811 | /* Add an item to a proto_tree, using the text label registered to that item;
2812 | the item is extracted from the tvbuff handed to it. */
2813 | static proto_item *
2814 | proto_tree_new_item(field_info *new_fi, proto_tree *tree,
2815 | tvbuff_t *tvb, int start, int length,
2816 | unsigned encoding)
2817 | {
2818 | proto_item *pi;
2819 | uint32_t value, n;
2820 | uint64_t value64;
2821 | ws_in4_addr ipv4_value;
2822 | float floatval;
2823 | double doubleval;
2824 | const char *stringval = NULL((void*)0);
2825 | nstime_t time_stamp;
2826 | bool_Bool length_error;
2827 |
2828 | /* Ensure that the newly created fvalue_t is freed if we throw an
2829 | * exception before adding it to the tree. (gcc creates clobbering
2830 | * when it optimizes the equivalent TRY..EXCEPT implementation.)
2831 | * XXX: Move the new_field_info() call inside here?
2832 | */
2833 | 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));
2834 |
2835 | switch (new_fi->hfinfo->type) {
2836 | case FT_NONE:
2837 | /* no value to set for FT_NONE */
2838 | break;
2839 |
2840 | case FT_PROTOCOL:
2841 | /* Set the protocol_tvb via the start offset, but include
2842 | * rest of the ds_tvb so that if finfo_set_len is called
2843 | * later it can be lengthened as much as possible. */
2844 | proto_tree_set_protocol_tvb(new_fi, new_fi->ds_tvb ? tvb_new_subset_remaining(new_fi->ds_tvb, new_fi->start) : NULL((void*)0), new_fi->hfinfo->name, length);
2845 | break;
2846 |
2847 | case FT_BYTES:
2848 | proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
2849 | break;
2850 |
2851 | case FT_UINT_BYTES:
2852 | n = get_uint_value(tree, tvb, start, length, encoding);
2853 | proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
2854 |
2855 | /* Instead of calling proto_item_set_len(), since we don't yet
2856 | * have a proto_item, we set the field_info's length ourselves. */
2857 | new_fi->length = n + length;
2858 | break;
2859 |
2860 | case FT_BOOLEAN:
2861 | /*
2862 | * Map all non-zero values to little-endian for
2863 | * backwards compatibility.
2864 | */
2865 | if (encoding)
2866 | encoding = ENC_LITTLE_ENDIAN0x80000000;
2867 | proto_tree_set_boolean(new_fi,
2868 | get_uint64_value(tree, tvb, start, length, encoding));
2869 | break;
2870 |
2871 | case FT_CHAR:
2872 | /* XXX - make these just FT_UINT? */
2873 | case FT_UINT8:
2874 | case FT_UINT16:
2875 | case FT_UINT24:
2876 | case FT_UINT32:
2877 | if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2878 | new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2879 | value = (uint32_t)value64;
2880 | if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2881 | new_fi->flags |= FI_VARINT0x00040000;
2882 | }
2883 | }
2884 | else {
2885 | /*
2886 | * Map all non-zero values to little-endian for
2887 | * backwards compatibility.
2888 | */
2889 | if (encoding)
2890 | encoding = ENC_LITTLE_ENDIAN0x80000000;
2891 |
2892 | value = get_uint_value(tree, tvb, start, length, encoding);
2893 | }
2894 | proto_tree_set_uint(new_fi, value);
2895 | break;
2896 |
2897 | case FT_UINT40:
2898 | case FT_UINT48:
2899 | case FT_UINT56:
2900 | case FT_UINT64:
2901 | if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2902 | new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2903 | if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2904 | new_fi->flags |= FI_VARINT0x00040000;
2905 | }
2906 | }
2907 | else {
2908 | /*
2909 | * Map all other non-zero values to little-endian for
2910 | * backwards compatibility.
2911 | */
2912 | if (encoding)
2913 | encoding = ENC_LITTLE_ENDIAN0x80000000;
2914 |
2915 | value64 = get_uint64_value(tree, tvb, start, length, encoding);
2916 | }
2917 | proto_tree_set_uint64(new_fi, value64);
2918 | break;
2919 |
2920 | /* XXX - make these just FT_INT? */
2921 | case FT_INT8:
2922 | case FT_INT16:
2923 | case FT_INT24:
2924 | case FT_INT32:
2925 | /*
2926 | * Map all non-zero values to little-endian for
2927 | * backwards compatibility.
2928 | */
2929 | if (encoding)
2930 | encoding = ENC_LITTLE_ENDIAN0x80000000;
2931 | proto_tree_set_int(new_fi,
2932 | get_int_value(tree, tvb, start, length, encoding));
2933 | break;
2934 |
2935 | case FT_INT40:
2936 | case FT_INT48:
2937 | case FT_INT56:
2938 | case FT_INT64:
2939 | /*
2940 | * Map all non-zero values to little-endian for
2941 | * backwards compatibility.
2942 | */
2943 | if (encoding)
2944 | encoding = ENC_LITTLE_ENDIAN0x80000000;
2945 | proto_tree_set_int64(new_fi,
2946 | get_int64_value(tree, tvb, start, length, encoding));
2947 | break;
2948 |
2949 | case FT_IPv4:
2950 | /*
2951 | * Map all non-zero values to little-endian for
2952 | * backwards compatibility.
2953 | */
2954 | if (encoding)
2955 | encoding = ENC_LITTLE_ENDIAN0x80000000;
2956 | if (length != FT_IPv4_LEN4) {
2957 | length_error = length < FT_IPv4_LEN4 ? true1 : false0;
2958 | report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
2959 | }
2960 | ipv4_value = tvb_get_ipv4(tvb, start);
2961 | /*
2962 | * NOTE: to support code written when
2963 | * proto_tree_add_item() took a bool as its
2964 | * last argument, with false meaning "big-endian"
2965 | * and true meaning "little-endian", we treat any
2966 | * non-zero value of "encoding" as meaning
2967 | * "little-endian".
2968 | */
2969 | 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);
2970 | break;
2971 |
2972 | case FT_IPXNET:
2973 | if (length != FT_IPXNET_LEN4) {
2974 | length_error = length < FT_IPXNET_LEN4 ? true1 : false0;
2975 | report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
2976 | }
2977 | proto_tree_set_ipxnet(new_fi,
2978 | get_uint_value(tree, tvb, start, FT_IPXNET_LEN4, ENC_BIG_ENDIAN0x00000000));
2979 | break;
2980 |
2981 | case FT_IPv6:
2982 | if (length != FT_IPv6_LEN16) {
2983 | length_error = length < FT_IPv6_LEN16 ? true1 : false0;
2984 | report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
2985 | }
2986 | proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
2987 | break;
2988 |
2989 | case FT_FCWWN:
2990 | if (length != FT_FCWWN_LEN8) {
2991 | length_error = length < FT_FCWWN_LEN8 ? true1 : false0;
2992 | report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
2993 | }
2994 | proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
2995 | break;
2996 |
2997 | case FT_AX25:
2998 | if (length != 7) {
2999 | length_error = length < 7 ? true1 : false0;
3000 | report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
3001 | }
3002 | proto_tree_set_ax25_tvb(new_fi, tvb, start);
3003 | break;
3004 |
3005 | case FT_VINES:
3006 | if (length != VINES_ADDR_LEN6) {
3007 | length_error = length < VINES_ADDR_LEN6 ? true1 : false0;
3008 | report_type_length_mismatch(tree, "a Vines address", length, length_error);
3009 | }
3010 | proto_tree_set_vines_tvb(new_fi, tvb, start);
3011 | break;
3012 |
3013 | case FT_ETHER:
3014 | if (length != FT_ETHER_LEN6) {
3015 | length_error = length < FT_ETHER_LEN6 ? true1 : false0;
3016 | report_type_length_mismatch(tree, "a MAC address", length, length_error);
3017 | }
3018 | proto_tree_set_ether_tvb(new_fi, tvb, start);
3019 | break;
3020 |
3021 | case FT_EUI64:
3022 | /*
3023 | * Map all non-zero values to little-endian for
3024 | * backwards compatibility.
3025 | */
3026 | if (encoding)
3027 | encoding = ENC_LITTLE_ENDIAN0x80000000;
3028 | if (length != FT_EUI64_LEN8) {
3029 | length_error = length < FT_EUI64_LEN8 ? true1 : false0;
3030 | report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
3031 | }
3032 | proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
3033 | break;
3034 | case FT_GUID:
3035 | /*
3036 | * Map all non-zero values to little-endian for
3037 | * backwards compatibility.
3038 | */
3039 | if (encoding)
3040 | encoding = ENC_LITTLE_ENDIAN0x80000000;
3041 | if (length != FT_GUID_LEN16) {
3042 | length_error = length < FT_GUID_LEN16 ? true1 : false0;
3043 | report_type_length_mismatch(tree, "a GUID", length, length_error);
3044 | }
3045 | proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
3046 | break;
3047 |
3048 | case FT_OID:
3049 | case FT_REL_OID:
3050 | proto_tree_set_oid_tvb(new_fi, tvb, start, length);
3051 | break;
3052 |
3053 | case FT_SYSTEM_ID:
3054 | proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
3055 | break;
3056 |
3057 | case FT_FLOAT:
3058 | /*
3059 | * NOTE: to support code written when
3060 | * proto_tree_add_item() took a bool as its
3061 | * last argument, with false meaning "big-endian"
3062 | * and true meaning "little-endian", we treat any
3063 | * non-zero value of "encoding" as meaning
3064 | * "little-endian".
3065 | *
3066 | * At some point in the future, we might
3067 | * support non-IEEE-binary floating-point
3068 | * formats in the encoding as well
3069 | * (IEEE decimal, System/3x0, VAX).
3070 | */
3071 | if (encoding)
3072 | encoding = ENC_LITTLE_ENDIAN0x80000000;
3073 | if (length != 4) {
3074 | length_error = length < 4 ? true1 : false0;
3075 | report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
3076 | }
3077 | if (encoding)
3078 | floatval = tvb_get_letohieee_float(tvb, start);
3079 | else
3080 | floatval = tvb_get_ntohieee_float(tvb, start);
3081 | proto_tree_set_float(new_fi, floatval);
3082 | break;
3083 |
3084 | case FT_DOUBLE:
3085 | /*
3086 | * NOTE: to support code written when
3087 | * proto_tree_add_item() took a bool as its
3088 | * last argument, with false meaning "big-endian"
3089 | * and true meaning "little-endian", we treat any
3090 | * non-zero value of "encoding" as meaning
3091 | * "little-endian".
3092 | *
3093 | * At some point in the future, we might
3094 | * support non-IEEE-binary floating-point
3095 | * formats in the encoding as well
3096 | * (IEEE decimal, System/3x0, VAX).
3097 | */
3098 | if (encoding == true1)
3099 | encoding = ENC_LITTLE_ENDIAN0x80000000;
3100 | if (length != 8) {
3101 | length_error = length < 8 ? true1 : false0;
3102 | report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
3103 | }
3104 | if (encoding)
3105 | doubleval = tvb_get_letohieee_double(tvb, start);
3106 | else
3107 | doubleval = tvb_get_ntohieee_double(tvb, start);
3108 | proto_tree_set_double(new_fi, doubleval);
3109 | break;
3110 |
3111 | case FT_STRING:
3112 | stringval = (const char*)get_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3113 | tvb, start, length, &length, encoding);
3114 | proto_tree_set_string(new_fi, stringval);
3115 |
3116 | /* Instead of calling proto_item_set_len(), since we
3117 | * don't yet have a proto_item, we set the
3118 | * field_info's length ourselves.
3119 | *
3120 | * XXX - our caller can't use that length to
3121 | * advance an offset unless they arrange that
3122 | * there always be a protocol tree into which
3123 | * we're putting this item.
3124 | */
3125 | new_fi->length = length;
3126 | break;
3127 |
3128 | case FT_STRINGZ:
3129 | stringval = (const char*)get_stringz_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3130 | tree, tvb, start, length, &length, encoding);
3131 | proto_tree_set_string(new_fi, stringval);
3132 |
3133 | /* Instead of calling proto_item_set_len(),
3134 | * since we don't yet have a proto_item, we
3135 | * set the field_info's length ourselves.
3136 | *
3137 | * XXX - our caller can't use that length to
3138 | * advance an offset unless they arrange that
3139 | * there always be a protocol tree into which
3140 | * we're putting this item.
3141 | */
3142 | new_fi->length = length;
3143 | break;
3144 |
3145 | case FT_UINT_STRING:
3146 | /*
3147 | * NOTE: to support code written when
3148 | * proto_tree_add_item() took a bool as its
3149 | * last argument, with false meaning "big-endian"
3150 | * and true meaning "little-endian", if the
3151 | * encoding value is true, treat that as
3152 | * ASCII with a little-endian length.
3153 | *
3154 | * This won't work for code that passes
3155 | * arbitrary non-zero values; that code
3156 | * will need to be fixed.
3157 | */
3158 | if (encoding == true1)
3159 | encoding = ENC_ASCII0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3160 | stringval = (const char*)get_uint_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3161 | tree, tvb, start, length, &length, encoding);
3162 | proto_tree_set_string(new_fi, stringval);
3163 |
3164 | /* Instead of calling proto_item_set_len(), since we
3165 | * don't yet have a proto_item, we set the
3166 | * field_info's length ourselves.
3167 | *
3168 | * XXX - our caller can't use that length to
3169 | * advance an offset unless they arrange that
3170 | * there always be a protocol tree into which
3171 | * we're putting this item.
3172 | */
3173 | new_fi->length = length;
3174 | break;
3175 |
3176 | case FT_STRINGZPAD:
3177 | stringval = (const char*)get_stringzpad_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3178 | tvb, start, length, &length, encoding);
3179 | proto_tree_set_string(new_fi, stringval);
3180 |
3181 | /* Instead of calling proto_item_set_len(), since we
3182 | * don't yet have a proto_item, we set the
3183 | * field_info's length ourselves.
3184 | *
3185 | * XXX - our caller can't use that length to
3186 | * advance an offset unless they arrange that
3187 | * there always be a protocol tree into which
3188 | * we're putting this item.
3189 | */
3190 | new_fi->length = length;
3191 | break;
3192 |
3193 | case FT_STRINGZTRUNC:
3194 | stringval = (const char*)get_stringztrunc_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3195 | tvb, start, length, &length, encoding);
3196 | proto_tree_set_string(new_fi, stringval);
3197 |
3198 | /* Instead of calling proto_item_set_len(), since we
3199 | * don't yet have a proto_item, we set the
3200 | * field_info's length ourselves.
3201 | *
3202 | * XXX - our caller can't use that length to
3203 | * advance an offset unless they arrange that
3204 | * there always be a protocol tree into which
3205 | * we're putting this item.
3206 | */
3207 | new_fi->length = length;
3208 | break;
3209 |
3210 | case FT_ABSOLUTE_TIME:
3211 | /*
3212 | * Absolute times can be in any of a number of
3213 | * formats, and they can be big-endian or
3214 | * little-endian.
3215 | *
3216 | * Historically FT_TIMEs were only timespecs;
3217 | * the only question was whether they were stored
3218 | * in big- or little-endian format.
3219 | *
3220 | * For backwards compatibility, we interpret an
3221 | * encoding of 1 as meaning "little-endian timespec",
3222 | * so that passing true is interpreted as that.
3223 | */
3224 | if (encoding == true1)
3225 | encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3226 |
3227 | get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
3228 |
3229 | proto_tree_set_time(new_fi, &time_stamp);
3230 | break;
3231 |
3232 | case FT_RELATIVE_TIME:
3233 | /*
3234 | * Relative times can be in any of a number of
3235 | * formats, and they can be big-endian or
3236 | * little-endian.
3237 | *
3238 | * Historically FT_TIMEs were only timespecs;
3239 | * the only question was whether they were stored
3240 | * in big- or little-endian format.
3241 | *
3242 | * For backwards compatibility, we interpret an
3243 | * encoding of 1 as meaning "little-endian timespec",
3244 | * so that passing true is interpreted as that.
3245 | */
3246 | if (encoding == true1)
3247 | encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3248 |
3249 | get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
3250 |
3251 | proto_tree_set_time(new_fi, &time_stamp);
3252 | break;
3253 | case FT_IEEE_11073_SFLOAT:
3254 | if (encoding)
3255 | encoding = ENC_LITTLE_ENDIAN0x80000000;
3256 | if (length != 2) {
3257 | length_error = length < 2 ? true1 : false0;
3258 | report_type_length_mismatch(tree, "a IEEE 11073 SFLOAT", length, length_error);
3259 | }
3260 |
3261 | fvalue_set_uinteger(new_fi->value, tvb_get_uint16(tvb, start, encoding));
3262 |
3263 | break;
3264 | case FT_IEEE_11073_FLOAT:
3265 | if (encoding)
3266 | encoding = ENC_LITTLE_ENDIAN0x80000000;
3267 | if (length != 4) {
3268 | length_error = length < 4 ? true1 : false0;
3269 | report_type_length_mismatch(tree, "a IEEE 11073 FLOAT", length, length_error);
3270 | }
3271 | fvalue_set_uinteger(new_fi->value, tvb_get_uint32(tvb, start, encoding));
3272 |
3273 | break;
3274 | default:
3275 | 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))
3276 | 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))
3277 | 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))
3278 | 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));
3279 | break;
3280 | }
3281 | 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);
3282 |
3283 | /* Don't add new node to proto_tree until now so that any exceptions
3284 | * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
3285 | /* XXX. wouldn't be better to add this item to tree, with some special
3286 | * flag (FI_EXCEPTION?) to know which item caused exception? For
3287 | * strings and bytes, we would have to set new_fi->value to something
3288 | * non-NULL, or otherwise ensure that proto_item_fill_display_label
3289 | * could handle NULL values. */
3290 | CLEANUP_POPexcept_pop(); if (0) except_cl.except_func(except_cl.except_context ); }
3291 | pi = proto_tree_add_node(tree, new_fi);
3292 |
3293 | switch (new_fi->hfinfo->type) {
3294 |
3295 | case FT_STRING:
3296 | /* XXX: trailing stray character detection should be done
3297 | * _before_ conversion to UTF-8, because conversion can change
3298 | * the length, or else get_string_length should return a value
3299 | * for the "length in bytes of the string after conversion
3300 | * including internal nulls." (Noting that we do, for other
3301 | * reasons, still need the "length in bytes in the field",
3302 | * especially for FT_STRINGZ.)
3303 | *
3304 | * This is true even for ASCII and UTF-8, because
3305 | * substituting REPLACEMENT CHARACTERS for illegal characters
3306 | * can also do so (and for UTF-8 possibly even make the
3307 | * string _shorter_).
3308 | */
3309 | detect_trailing_stray_characters(encoding, stringval, length, pi);
3310 | break;
3311 |
3312 | default:
3313 | break;
3314 | }
3315 |
3316 | return pi;
3317 | }
3318 |
3319 | proto_item *
3320 | proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3321 | const int start, int length,
3322 | const unsigned encoding, int32_t *retval)
3323 | {
3324 | header_field_info *hfinfo;
3325 | field_info *new_fi;
3326 | int32_t value;
3327 |
3328 | 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", 3328, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3328, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3328, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3329 |
3330 | switch (hfinfo->type) {
3331 | case FT_INT8:
3332 | case FT_INT16:
3333 | case FT_INT24:
3334 | case FT_INT32:
3335 | break;
3336 | case FT_INT64:
3337 | 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)
3338 | hfinfo->abbrev)proto_report_dissector_bug("64-bit signed integer field %s used with proto_tree_add_item_ret_int()" , hfinfo->abbrev);
3339 | default:
3340 | 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)
3341 | hfinfo->abbrev)proto_report_dissector_bug("Non-signed-integer field %s used with proto_tree_add_item_ret_int()" , hfinfo->abbrev);
3342 | }
3343 |
3344 | CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3345 | {if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3346 | if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3347 | {if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3348 | *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3349 | }if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3350 | } )if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); };
3351 |
3352 | if (encoding & ENC_STRING0x07000000) {
3353 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3354 | }
3355 | /* I believe it's ok if this is called with a NULL tree */
3356 | value = get_int_value(tree, tvb, start, length, encoding);
3357 |
3358 | if (retval) {
3359 | int no_of_bits;
3360 | *retval = value;
3361 | if (hfinfo->bitmask) {
3362 | /* Mask out irrelevant portions */
3363 | *retval &= (uint32_t)(hfinfo->bitmask);
3364 | /* Shift bits */
3365 | *retval >>= hfinfo_bitshift(hfinfo);
3366 | }
3367 | no_of_bits = ws_count_ones(hfinfo->bitmask);
3368 | *retval = ws_sign_ext32(*retval, no_of_bits);
3369 | }
3370 |
3371 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3372 |
3373 | 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", 3373 , __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", 3373, "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", 3373, "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", 3373, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
3374 |
3375 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3376 |
3377 | proto_tree_set_int(new_fi, value);
3378 |
3379 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3380 |
3381 | return proto_tree_add_node(tree, new_fi);
3382 | }
3383 |
3384 | proto_item *
3385 | proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3386 | const int start, int length,
3387 | const unsigned encoding, uint32_t *retval)
3388 | {
3389 | header_field_info *hfinfo;
3390 | field_info *new_fi;
3391 | uint32_t value;
3392 |
3393 | 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", 3393, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3393, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3393, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3394 |
3395 | switch (hfinfo->type) {
3396 | case FT_CHAR:
3397 | case FT_UINT8:
3398 | case FT_UINT16:
3399 | case FT_UINT24:
3400 | case FT_UINT32:
3401 | break;
3402 | default:
3403 | 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)
3404 | 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);
3405 | }
3406 |
3407 | if (length == 0) {
3408 | if (retval) {
3409 | *retval = 0;
3410 | }
3411 | return NULL((void*)0);
3412 | }
3413 |
3414 | if (encoding & ENC_STRING0x07000000) {
3415 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3416 | }
3417 | /* I believe it's ok if this is called with a NULL tree */
3418 | /* XXX - modify if we ever support EBCDIC FT_CHAR */
3419 | if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3420 | uint64_t temp64;
3421 | tvb_get_varint(tvb, start, length, &temp64, encoding);
3422 | value = (uint32_t)temp64;
3423 | } else {
3424 | value = get_uint_value(tree, tvb, start, length, encoding);
3425 | }
3426 |
3427 | if (retval) {
3428 | *retval = value;
3429 | if (hfinfo->bitmask) {
3430 | /* Mask out irrelevant portions */
3431 | *retval &= (uint32_t)(hfinfo->bitmask);
3432 | /* Shift bits */
3433 | *retval >>= hfinfo_bitshift(hfinfo);
3434 | }
3435 | }
3436 |
3437 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3438 |
3439 | 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", 3439 , __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", 3439, "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", 3439, "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", 3439, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
3440 |
3441 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3442 |
3443 | proto_tree_set_uint(new_fi, value);
3444 |
3445 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3446 | if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3447 | new_fi->flags |= FI_VARINT0x00040000;
3448 | }
3449 | return proto_tree_add_node(tree, new_fi);
3450 | }
3451 |
3452 | proto_item *
3453 | proto_tree_add_item_ret_uint32(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3454 | const int start, int length,
3455 | const unsigned encoding, uint32_t *retval)
3456 | {
3457 | return proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, retval);
3458 | }
3459 |
3460 | proto_item *
3461 | proto_tree_add_item_ret_uint8(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3462 | const int start, int length,
3463 | const unsigned encoding, uint8_t *retval)
3464 | {
3465 | /* TODO: further restrict by hfinfo->type ? */
3466 | uint32_t val32;
3467 | proto_item *item = proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, &val32);
3468 | *retval = (uint8_t)val32;
3469 | return item;
3470 | }
3471 |
3472 | proto_item *
3473 | proto_tree_add_item_ret_uint16(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3474 | const int start, int length,
3475 | const unsigned encoding, uint16_t *retval)
3476 | {
3477 | /* TODO: further restrict by hfinfo->type ? */
3478 | uint32_t val32;
3479 | proto_item *item = proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, &val32);
3480 | *retval = (uint16_t)(val32 & 0xFFFF); /* Bitwise AND is a classic 'Reset' for taint */
3481 | return item;
3482 | }
3483 |
3484 |
3485 | /* Gets data from tvbuff, adds it to proto_tree, increments offset,
3486 | * and returns proto_item* and uint value retrieved*/
3487 | proto_item *
3488 | ptvcursor_add_ret_uint(ptvcursor_t *ptvc, int hfindex, unsigned length,
3489 | const unsigned encoding, uint32_t *retval)
3490 | {
3491 | field_info *new_fi;
3492 | header_field_info *hfinfo;
3493 | unsigned item_length;
3494 | unsigned offset;
3495 | uint32_t value;
3496 |
3497 | offset = ptvc->offset;
3498 | 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", 3498, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3498, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3498, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3499 |
3500 | switch (hfinfo->type) {
3501 | case FT_CHAR:
3502 | case FT_UINT8:
3503 | case FT_UINT16:
3504 | case FT_UINT24:
3505 | case FT_UINT32:
3506 | break;
3507 | default:
3508 | 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)
3509 | 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);
3510 | }
3511 |
3512 | get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3513 | test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3514 |
3515 | /* I believe it's ok if this is called with a NULL tree */
3516 | /* XXX - modify if we ever support EBCDIC FT_CHAR */
3517 | value = get_uint_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3518 |
3519 | if (retval) {
3520 | *retval = value;
3521 | if (hfinfo->bitmask) {
3522 | /* Mask out irrelevant portions */
3523 | *retval &= (uint32_t)(hfinfo->bitmask);
3524 | /* Shift bits */
3525 | *retval >>= hfinfo_bitshift(hfinfo);
3526 | }
3527 | }
3528 |
3529 | ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3530 |
3531 | CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3532 |
3533 | /* Coast clear. Try and fake it */
3534 | 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", 3534 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3534, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3534, "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", 3534, __func__, "Adding %s would put more than %d 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); } } };
3535 |
3536 | new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3537 |
3538 | return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3539 | offset, length, encoding);
3540 | }
3541 |
3542 | /* Gets data from tvbuff, adds it to proto_tree, increments offset,
3543 | * and returns proto_item* and int value retrieved*/
3544 | proto_item *
3545 | ptvcursor_add_ret_int(ptvcursor_t *ptvc, int hfindex, unsigned length,
3546 | const unsigned encoding, int32_t *retval)
3547 | {
3548 | field_info *new_fi;
3549 | header_field_info *hfinfo;
3550 | unsigned item_length;
3551 | unsigned offset;
3552 | uint32_t value;
3553 |
3554 | offset = ptvc->offset;
3555 | 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", 3555, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3555, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3555, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3556 |
3557 | switch (hfinfo->type) {
3558 | case FT_INT8:
3559 | case FT_INT16:
3560 | case FT_INT24:
3561 | case FT_INT32:
3562 | break;
3563 | default:
3564 | 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)
3565 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32" , hfinfo->abbrev);
3566 | }
3567 |
3568 | get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3569 | test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3570 |
3571 | /* I believe it's ok if this is called with a NULL tree */
3572 | /* XXX - modify if we ever support EBCDIC FT_CHAR */
3573 | value = get_int_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3574 |
3575 | if (retval) {
3576 | int no_of_bits;
3577 | *retval = value;
3578 | if (hfinfo->bitmask) {
3579 | /* Mask out irrelevant portions */
3580 | *retval &= (uint32_t)(hfinfo->bitmask);
3581 | /* Shift bits */
3582 | *retval >>= hfinfo_bitshift(hfinfo);
3583 | }
3584 | no_of_bits = ws_count_ones(hfinfo->bitmask);
3585 | *retval = ws_sign_ext32(*retval, no_of_bits);
3586 | }
3587 |
3588 | ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3589 |
3590 | CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3591 |
3592 | /* Coast clear. Try and fake it */
3593 | 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", 3593 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3593, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3593, "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", 3593, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((ptvc->tree )->tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf (((ptvc->tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((ptvc ->tree)->tree_data)->visible)) { if (proto_item_is_hidden ((ptvc->tree))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT ) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo->type != FT_PROTOCOL || ((ptvc->tree)->tree_data )->fake_protocols)) { ((void)0); return proto_tree_add_fake_node (ptvc->tree, hfinfo); } } };
3594 |
3595 | new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3596 |
3597 | return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3598 | offset, length, encoding);
3599 | }
3600 |
3601 | /* Gets data from tvbuff, adds it to proto_tree, increments offset,
3602 | * and returns proto_item* and string value retrieved */
3603 | proto_item*
3604 | ptvcursor_add_ret_string(ptvcursor_t* ptvc, int hf, int length, const unsigned encoding, wmem_allocator_t *scope, const uint8_t **retval)
3605 | {
3606 | header_field_info *hfinfo;
3607 | field_info *new_fi;
3608 | const uint8_t *value;
3609 | unsigned item_length;
3610 | unsigned offset;
3611 |
3612 | offset = ptvc->offset;
3613 |
3614 | 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", 3614 , __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", 3614, "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", 3614, "gpa_hfinfo.hfi[hf] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[hf];;
3615 |
3616 | switch (hfinfo->type) {
3617 | case FT_STRING:
3618 | value = get_string_value(scope, ptvc->tvb, offset, length, (int*)&item_length, encoding);
3619 | break;
3620 | case FT_STRINGZ:
3621 | value = get_stringz_value(scope, ptvc->tree, ptvc->tvb, offset, length, (int*)&item_length, encoding);
3622 | break;
3623 | case FT_UINT_STRING:
3624 | value = get_uint_string_value(scope, ptvc->tree, ptvc->tvb, offset, length, (int*)&item_length, encoding);
3625 | break;
3626 | case FT_STRINGZPAD:
3627 | value = get_stringzpad_value(scope, ptvc->tvb, offset, length, (int*)&item_length, encoding);
3628 | break;
3629 | case FT_STRINGZTRUNC:
3630 | value = get_stringztrunc_value(scope, ptvc->tvb, offset, length, (int*)&item_length, encoding);
3631 | break;
3632 | default:
3633 | 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)
3634 | 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);
3635 | }
3636 |
3637 | if (retval)
3638 | *retval = value;
3639 |
3640 | ptvcursor_advance(ptvc, item_length);
3641 |
3642 | CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3643 |
3644 | 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", 3644, __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", 3644, "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", 3644, "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", 3644 , __func__, "Adding %s would put more than %d 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); } } };
3645 |
3646 | new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3647 |
3648 | return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3649 | offset, length, encoding);
3650 | }
3651 |
3652 | /* Gets data from tvbuff, adds it to proto_tree, increments offset,
3653 | * and returns proto_item* and boolean value retrieved */
3654 | proto_item*
3655 | ptvcursor_add_ret_boolean(ptvcursor_t* ptvc, int hfindex, unsigned length, const unsigned encoding, bool_Bool *retval)
3656 | {
3657 | header_field_info *hfinfo;
3658 | field_info *new_fi;
3659 | unsigned item_length;
3660 | unsigned offset;
3661 | uint64_t value, bitval;
3662 |
3663 | offset = ptvc->offset;
3664 | 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", 3664, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3664, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3664, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3665 |
3666 | if (hfinfo->type != FT_BOOLEAN) {
3667 | 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)
3668 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN" , hfinfo->abbrev);
3669 | }
3670 |
3671 | if (length == 0) {
3672 | if (retval) {
3673 | *retval = 0;
3674 | }
3675 | return NULL((void*)0);
3676 | }
3677 | if (encoding & ENC_STRING0x07000000) {
3678 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3679 | }
3680 |
3681 | get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3682 | test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3683 |
3684 | /* I believe it's ok if this is called with a NULL tree */
3685 | value = get_uint64_value(ptvc->tree, ptvc->tvb, offset, length, encoding);
3686 |
3687 | if (retval) {
3688 | bitval = value;
3689 | if (hfinfo->bitmask) {
3690 | /* Mask out irrelevant portions */
3691 | bitval &= hfinfo->bitmask;
3692 | }
3693 | *retval = (bitval != 0);
3694 | }
3695 |
3696 | ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3697 |
3698 | CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3699 |
3700 | 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", 3700, __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", 3700, "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", 3700, "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", 3700 , __func__, "Adding %s would put more than %d 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); } } };
3701 |
3702 | new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3703 |
3704 | return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3705 | offset, length, encoding);
3706 | }
3707 |
3708 | proto_item *
3709 | proto_tree_add_item_ret_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3710 | const int start, int length, const unsigned encoding, uint64_t *retval)
3711 | {
3712 | header_field_info *hfinfo;
3713 | field_info *new_fi;
3714 | uint64_t value;
3715 |
3716 | 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", 3716, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3716, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3716, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3717 |
3718 | switch (hfinfo->type) {
3719 | case FT_UINT40:
3720 | case FT_UINT48:
3721 | case FT_UINT56:
3722 | case FT_UINT64:
3723 | break;
3724 | default:
3725 | 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)
3726 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64" , hfinfo->abbrev);
3727 | }
3728 |
3729 | CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3730 | {if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3731 | if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3732 | {if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3733 | *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3734 | }if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3735 | } )if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); };
3736 |
3737 | if (encoding & ENC_STRING0x07000000) {
3738 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3739 | }
3740 | /* I believe it's ok if this is called with a NULL tree */
3741 | if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3742 | tvb_get_varint(tvb, start, length, &value, encoding);
3743 | } else {
3744 | value = get_uint64_value(tree, tvb, start, length, encoding);
3745 | }
3746 |
3747 | if (retval) {
3748 | *retval = value;
3749 | if (hfinfo->bitmask) {
3750 | /* Mask out irrelevant portions */
3751 | *retval &= hfinfo->bitmask;
3752 | /* Shift bits */
3753 | *retval >>= hfinfo_bitshift(hfinfo);
3754 | }
3755 | }
3756 |
3757 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3758 |
3759 | 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", 3759 , __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", 3759, "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", 3759, "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", 3759, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
3760 |
3761 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3762 |
3763 | proto_tree_set_uint64(new_fi, value);
3764 |
3765 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3766 | if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3767 | new_fi->flags |= FI_VARINT0x00040000;
3768 | }
3769 |
3770 | return proto_tree_add_node(tree, new_fi);
3771 | }
3772 |
3773 | proto_item *
3774 | proto_tree_add_item_ret_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3775 | const int start, int length, const unsigned encoding, int64_t *retval)
3776 | {
3777 | header_field_info *hfinfo;
3778 | field_info *new_fi;
3779 | int64_t value;
3780 |
3781 | 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", 3781, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3781, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3781, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3782 |
3783 | switch (hfinfo->type) {
3784 | case FT_INT40:
3785 | case FT_INT48:
3786 | case FT_INT56:
3787 | case FT_INT64:
3788 | break;
3789 | default:
3790 | 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)
3791 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64" , hfinfo->abbrev);
3792 | }
3793 |
3794 | CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3795 | {if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3796 | if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3797 | {if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3798 | *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3799 | }if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3800 | } )if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); };
3801 |
3802 | if (encoding & ENC_STRING0x07000000) {
3803 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3804 | }
3805 | /* I believe it's ok if this is called with a NULL tree */
3806 | if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3807 | tvb_get_varint(tvb, start, length, (uint64_t*)&value, encoding);
3808 | }
3809 | else {
3810 | value = get_int64_value(tree, tvb, start, length, encoding);
3811 | }
3812 |
3813 | if (retval) {
3814 | *retval = value;
3815 | }
3816 |
3817 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3818 |
3819 | 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", 3819 , __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", 3819, "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", 3819, "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", 3819, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
3820 |
3821 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3822 |
3823 | proto_tree_set_int64(new_fi, value);
3824 |
3825 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3826 | if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3827 | new_fi->flags |= FI_VARINT0x00040000;
3828 | }
3829 |
3830 | return proto_tree_add_node(tree, new_fi);
3831 | }
3832 |
3833 | proto_item *
3834 | proto_tree_add_item_ret_varint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3835 | const int start, int length, const unsigned encoding, uint64_t *retval, int *lenretval)
3836 | {
3837 | header_field_info *hfinfo;
3838 | field_info *new_fi;
3839 | uint64_t value;
3840 |
3841 | 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", 3841, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3841, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3841, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3842 |
3843 | 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 )))) {
3844 | 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)
3845 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT or FT_INT" , hfinfo->abbrev);
3846 | }
3847 |
3848 | /* length validation for native number encoding caught by get_uint64_value() */
3849 | /* length has to be -1 or > 0 regardless of encoding */
3850 | if (length == 0)
3851 | 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)
3852 | length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_varint" , length);
3853 |
3854 | if (encoding & ENC_STRING0x07000000) {
3855 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3856 | }
3857 |
3858 | length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value, encoding);
3859 |
3860 | if (retval) {
3861 | *retval = value;
3862 | if (hfinfo->bitmask) {
3863 | /* Mask out irrelevant portions */
3864 | *retval &= hfinfo->bitmask;
3865 | /* Shift bits */
3866 | *retval >>= hfinfo_bitshift(hfinfo);
3867 | }
3868 | }
3869 |
3870 | if (lenretval) {
3871 | *lenretval = length;
3872 | }
3873 |
3874 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3875 |
3876 | 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", 3876 , __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", 3876, "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", 3876, "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", 3876, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
3877 |
3878 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3879 |
3880 | proto_tree_set_uint64(new_fi, value);
3881 |
3882 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3883 | if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3884 | new_fi->flags |= FI_VARINT0x00040000;
3885 | }
3886 |
3887 | return proto_tree_add_node(tree, new_fi);
3888 |
3889 | }
3890 |
3891 | proto_item *
3892 | proto_tree_add_item_ret_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3893 | const int start, int length,
3894 | const unsigned encoding, bool_Bool *retval)
3895 | {
3896 | header_field_info *hfinfo;
3897 | field_info *new_fi;
3898 | uint64_t value, bitval;
3899 |
3900 | 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", 3900, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3900, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3900, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3901 |
3902 | if (hfinfo->type != FT_BOOLEAN) {
3903 | 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)
3904 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN" , hfinfo->abbrev);
3905 | }
3906 |
3907 | CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3908 | {if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3909 | if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3910 | {if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3911 | *retval = false;if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3912 | }if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3913 | } )if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); };
3914 |
3915 | if (encoding & ENC_STRING0x07000000) {
3916 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3917 | }
3918 | /* I believe it's ok if this is called with a NULL tree */
3919 | value = get_uint64_value(tree, tvb, start, length, encoding);
3920 |
3921 | if (retval) {
3922 | bitval = value;
3923 | if (hfinfo->bitmask) {
3924 | /* Mask out irrelevant portions */
3925 | bitval &= hfinfo->bitmask;
3926 | }
3927 | *retval = (bitval != 0);
3928 | }
3929 |
3930 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3931 |
3932 | 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", 3932 , __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", 3932, "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", 3932, "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", 3932, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
3933 |
3934 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3935 |
3936 | proto_tree_set_boolean(new_fi, value);
3937 |
3938 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3939 |
3940 | return proto_tree_add_node(tree, new_fi);
3941 | }
3942 |
3943 | proto_item *
3944 | proto_tree_add_item_ret_float(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3945 | const int start, int length,
3946 | const unsigned encoding, float *retval)
3947 | {
3948 | header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3949 | field_info *new_fi;
3950 | float value;
3951 |
3952 | 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", 3952, "hfinfo != ((void*)0)", "Not passed hfi!"))));
3953 |
3954 | if (hfinfo->type != FT_FLOAT) {
3955 | 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);
3956 | }
3957 |
3958 | if (length != 4) {
3959 | report_type_length_mismatch(tree, "a single-precision floating point number", length, true1);
3960 | }
3961 |
3962 | /* treat any nonzero encoding as little endian for backwards compatibility */
3963 | value = encoding ? tvb_get_letohieee_float(tvb, start) : tvb_get_ntohieee_float(tvb, start);
3964 | if (retval) {
3965 | *retval = value;
3966 | }
3967 |
3968 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3969 |
3970 | 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", 3970 , __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", 3970, "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", 3970, "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", 3970, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
3971 |
3972 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3973 | if (encoding) {
3974 | new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
3975 | }
3976 |
3977 | proto_tree_set_float(new_fi, value);
3978 |
3979 | return proto_tree_add_node(tree, new_fi);
3980 | }
3981 |
3982 | proto_item *
3983 | proto_tree_add_item_ret_double(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3984 | const int start, int length,
3985 | const unsigned encoding, double *retval)
3986 | {
3987 | header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3988 | field_info *new_fi;
3989 | double value;
3990 |
3991 | 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", 3991, "hfinfo != ((void*)0)", "Not passed hfi!"))));
3992 |
3993 | if (hfinfo->type != FT_DOUBLE) {
3994 | 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);
3995 | }
3996 |
3997 | if (length != 8) {
3998 | report_type_length_mismatch(tree, "a double-precision floating point number", length, true1);
3999 | }
4000 |
4001 | /* treat any nonzero encoding as little endian for backwards compatibility */
4002 | value = encoding ? tvb_get_letohieee_double(tvb, start) : tvb_get_ntohieee_double(tvb, start);
4003 | if (retval) {
4004 | *retval = value;
4005 | }
4006 |
4007 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4008 |
4009 | 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", 4009 , __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", 4009, "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", 4009, "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", 4009, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4010 |
4011 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4012 | if (encoding) {
4013 | new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
4014 | }
4015 |
4016 | proto_tree_set_double(new_fi, value);
4017 |
4018 | return proto_tree_add_node(tree, new_fi);
4019 | }
4020 |
4021 | proto_item *
4022 | proto_tree_add_item_ret_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4023 | const int start, int length,
4024 | const unsigned encoding, ws_in4_addr *retval)
4025 | {
4026 | header_field_info *hfinfo;
4027 | field_info *new_fi;
4028 | ws_in4_addr value;
4029 |
4030 | 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", 4030, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4030, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4030, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4031 |
4032 | switch (hfinfo->type) {
4033 | case FT_IPv4:
4034 | break;
4035 | default:
4036 | 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)
4037 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv4", hfinfo->abbrev);
4038 | }
4039 |
4040 | if (length != FT_IPv4_LEN4)
4041 | 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)
4042 | length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv4" , length);
4043 |
4044 | if (encoding & (ENC_STRING0x07000000 | ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010))) {
4045 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
4046 | }
4047 |
4048 | /*
4049 | * NOTE: to support code written when proto_tree_add_item() took
4050 | * a bool as its last argument, with false meaning "big-endian"
4051 | * and true meaning "little-endian", we treat any non-zero value
4052 | * of "encoding" as meaning "little-endian".
4053 | */
4054 | value = tvb_get_ipv4(tvb, start);
4055 | if (encoding)
4056 | 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))));
4057 |
4058 | if (retval) {
4059 | *retval = value;
4060 | }
4061 |
4062 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4063 |
4064 | 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", 4064 , __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", 4064, "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", 4064, "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", 4064, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4065 |
4066 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4067 |
4068 | proto_tree_set_ipv4(new_fi, value);
4069 |
4070 | new_fi->flags |= encoding ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4071 | return proto_tree_add_node(tree, new_fi);
4072 | }
4073 |
4074 | proto_item *
4075 | proto_tree_add_item_ret_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4076 | const int start, int length,
4077 | const unsigned encoding, ws_in6_addr *addr)
4078 | {
4079 | header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4080 | field_info *new_fi;
4081 |
4082 | 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", 4082, "hfinfo != ((void*)0)", "Not passed hfi!"))));
4083 |
4084 | switch (hfinfo->type) {
4085 | case FT_IPv6:
4086 | break;
4087 | default:
4088 | 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)
4089 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv6", hfinfo->abbrev);
4090 | }
4091 |
4092 | if (length != FT_IPv6_LEN16)
4093 | 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)
4094 | length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv6" , length);
4095 |
4096 | if (encoding) {
4097 | 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" );
4098 | }
4099 |
4100 | tvb_get_ipv6(tvb, start, addr);
4101 |
4102 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4103 |
4104 | 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", 4104 , __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", 4104, "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", 4104, "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", 4104, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4105 |
4106 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4107 |
4108 | proto_tree_set_ipv6(new_fi, addr);
4109 |
4110 | return proto_tree_add_node(tree, new_fi);
4111 | }
4112 |
4113 | proto_item *
4114 | proto_tree_add_item_ret_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4115 | const int start, int length, const unsigned encoding, uint8_t *retval) {
4116 |
4117 | header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4118 | field_info *new_fi;
4119 |
4120 | 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", 4120, "hfinfo != ((void*)0)", "Not passed hfi!"))));
4121 |
4122 | switch (hfinfo->type) {
4123 | case FT_ETHER:
4124 | break;
4125 | default:
4126 | 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)
4127 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ETHER" , hfinfo->abbrev);
4128 | }
4129 |
4130 | if (length != FT_ETHER_LEN6)
4131 | 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)
4132 | length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ether" , length);
4133 |
4134 | if (encoding) {
4135 | 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" );
4136 | }
4137 |
4138 | tvb_memcpy(tvb, retval, start, length);
4139 |
4140 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4141 |
4142 | 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", 4142 , __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", 4142, "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", 4142, "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", 4142, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4143 |
4144 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4145 |
4146 | proto_tree_set_ether(new_fi, retval);
4147 |
4148 | return proto_tree_add_node(tree, new_fi);
4149 | }
4150 |
4151 |
4152 | proto_item *
4153 | proto_tree_add_item_ret_string_and_length(proto_tree *tree, int hfindex,
4154 | tvbuff_t *tvb,
4155 | const int start, int length,
4156 | const unsigned encoding,
4157 | wmem_allocator_t *scope,
4158 | const uint8_t **retval,
4159 | int *lenretval)
4160 | {
4161 | proto_item *pi;
4162 | header_field_info *hfinfo;
4163 | field_info *new_fi;
4164 | const uint8_t *value;
4165 |
4166 | 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", 4166, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4166, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4166, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4167 |
4168 | switch (hfinfo->type) {
4169 | case FT_STRING:
4170 | value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4171 | break;
4172 | case FT_STRINGZ:
4173 | value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4174 | break;
4175 | case FT_UINT_STRING:
4176 | value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4177 | break;
4178 | case FT_STRINGZPAD:
4179 | value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4180 | break;
4181 | case FT_STRINGZTRUNC:
4182 | value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4183 | break;
4184 | default:
4185 | 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)
4186 | 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);
4187 | }
4188 |
4189 | if (retval)
4190 | *retval = value;
4191 |
4192 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4193 |
4194 | 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", 4194 , __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", 4194, "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", 4194, "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", 4194, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4195 |
4196 | new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4197 |
4198 | proto_tree_set_string(new_fi, (const char*)value);
4199 |
4200 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4201 |
4202 | pi = proto_tree_add_node(tree, new_fi);
4203 |
4204 | switch (hfinfo->type) {
4205 |
4206 | case FT_STRINGZ:
4207 | case FT_STRINGZPAD:
4208 | case FT_STRINGZTRUNC:
4209 | case FT_UINT_STRING:
4210 | break;
4211 |
4212 | case FT_STRING:
4213 | detect_trailing_stray_characters(encoding, (const char*)value, length, pi);
4214 | break;
4215 |
4216 | default:
4217 | ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4217 , __func__, "assertion \"not reached\" failed");
4218 | }
4219 |
4220 | return pi;
4221 | }
4222 |
4223 | proto_item *
4224 | proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4225 | const int start, int length,
4226 | const unsigned encoding, wmem_allocator_t *scope,
4227 | const uint8_t **retval)
4228 | {
4229 | return proto_tree_add_item_ret_string_and_length(tree, hfindex,
4230 | tvb, start, length, encoding, scope, retval, &length);
4231 | }
4232 |
4233 | proto_item *
4234 | proto_tree_add_item_ret_display_string_and_length(proto_tree *tree, int hfindex,
4235 | tvbuff_t *tvb,
4236 | const int start, int length,
4237 | const unsigned encoding,
4238 | wmem_allocator_t *scope,
4239 | char **retval,
4240 | int *lenretval)
4241 | {
4242 | proto_item *pi;
4243 | header_field_info *hfinfo;
4244 | field_info *new_fi;
4245 | const uint8_t *value;
4246 | uint32_t n = 0;
4247 |
4248 | 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", 4248, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4248, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4248, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4249 |
4250 | switch (hfinfo->type) {
4251 | case FT_STRING:
4252 | value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4253 | *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4254 | ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4255 | break;
4256 | case FT_STRINGZ:
4257 | value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4258 | *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4259 | ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4260 | break;
4261 | case FT_UINT_STRING:
4262 | value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4263 | *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4264 | ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4265 | break;
4266 | case FT_STRINGZPAD:
4267 | value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4268 | *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4269 | ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4270 | break;
4271 | case FT_STRINGZTRUNC:
4272 | value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4273 | *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4274 | ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4275 | break;
4276 | case FT_BYTES:
4277 | tvb_ensure_bytes_exist(tvb, start, length);
4278 | value = tvb_get_ptr(tvb, start, length);
4279 | *retval = format_bytes_hfinfo(scope, hfinfo, value, length);
4280 | *lenretval = length;
4281 | break;
4282 | case FT_UINT_BYTES:
4283 | n = get_uint_value(tree, tvb, start, length, encoding);
4284 | tvb_ensure_bytes_exist(tvb, start + length, n);
4285 | value = tvb_get_ptr(tvb, start + length, n);
4286 | *retval = format_bytes_hfinfo(scope, hfinfo, value, n);
4287 | *lenretval = length + n;
4288 | break;
4289 | default:
4290 | 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)
4291 | 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);
4292 | }
4293 |
4294 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4295 |
4296 | 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", 4296 , __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", 4296, "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", 4296, "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", 4296, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4297 |
4298 | new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4299 |
4300 | switch (hfinfo->type) {
4301 |
4302 | case FT_STRING:
4303 | case FT_STRINGZ:
4304 | case FT_UINT_STRING:
4305 | case FT_STRINGZPAD:
4306 | case FT_STRINGZTRUNC:
4307 | proto_tree_set_string(new_fi, (const char*)value);
4308 | break;
4309 |
4310 | case FT_BYTES:
4311 | proto_tree_set_bytes(new_fi, value, length);
4312 | break;
4313 |
4314 | case FT_UINT_BYTES:
4315 | proto_tree_set_bytes(new_fi, value, n);
4316 | break;
4317 |
4318 | default:
4319 | ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4319 , __func__, "assertion \"not reached\" failed");
4320 | }
4321 |
4322 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4323 |
4324 | pi = proto_tree_add_node(tree, new_fi);
4325 |
4326 | switch (hfinfo->type) {
4327 |
4328 | case FT_STRINGZ:
4329 | case FT_STRINGZPAD:
4330 | case FT_STRINGZTRUNC:
4331 | case FT_UINT_STRING:
4332 | break;
4333 |
4334 | case FT_STRING:
4335 | detect_trailing_stray_characters(encoding, (const char*)value, length, pi);
4336 | break;
4337 |
4338 | case FT_BYTES:
4339 | case FT_UINT_BYTES:
4340 | break;
4341 |
4342 | default:
4343 | ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4343 , __func__, "assertion \"not reached\" failed");
4344 | }
4345 |
4346 | return pi;
4347 | }
4348 |
4349 | proto_item *
4350 | proto_tree_add_item_ret_display_string(proto_tree *tree, int hfindex,
4351 | tvbuff_t *tvb,
4352 | const int start, int length,
4353 | const unsigned encoding,
4354 | wmem_allocator_t *scope,
4355 | char **retval)
4356 | {
4357 | return proto_tree_add_item_ret_display_string_and_length(tree, hfindex,
4358 | tvb, start, length, encoding, scope, retval, &length);
4359 | }
4360 |
4361 | proto_item *
4362 | proto_tree_add_item_ret_time_string(proto_tree *tree, int hfindex,
4363 | tvbuff_t *tvb,
4364 | const int start, int length, const unsigned encoding,
4365 | wmem_allocator_t *scope, char **retval)
4366 | {
4367 | header_field_info *hfinfo;
4368 | field_info *new_fi;
4369 | nstime_t time_stamp;
4370 | int flags;
4371 |
4372 | 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", 4372, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4372, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4372, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4373 |
4374 | switch (hfinfo->type) {
4375 | case FT_ABSOLUTE_TIME:
4376 | get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
4377 | flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
4378 | if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
4379 | flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
4380 | }
4381 | *retval = abs_time_to_str_ex(scope, &time_stamp, hfinfo->display, flags);
4382 | break;
4383 | case FT_RELATIVE_TIME:
4384 | get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
4385 | *retval = rel_time_to_secs_str(scope, &time_stamp);
4386 | break;
4387 | default:
4388 | 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)
4389 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ABSOLUTE_TIME or FT_RELATIVE_TIME" , hfinfo->abbrev);
4390 | }
4391 |
4392 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4393 |
4394 | 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", 4394 , __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", 4394, "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", 4394, "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", 4394, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4395 |
4396 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4397 |
4398 | switch (hfinfo->type) {
4399 |
4400 | case FT_ABSOLUTE_TIME:
4401 | case FT_RELATIVE_TIME:
4402 | proto_tree_set_time(new_fi, &time_stamp);
4403 | break;
4404 | default:
4405 | ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4405 , __func__, "assertion \"not reached\" failed");
4406 | }
4407 |
4408 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4409 |
4410 | return proto_tree_add_node(tree, new_fi);
4411 | }
4412 |
4413 | /* Gets data from tvbuff, adds it to proto_tree, increments offset,
4414 | and returns proto_item* */
4415 | proto_item *
4416 | ptvcursor_add(ptvcursor_t *ptvc, int hfindex, int length,
4417 | const unsigned encoding)
4418 | {
4419 | field_info *new_fi;
4420 | header_field_info *hfinfo;
4421 | int item_length;
4422 | unsigned offset;
4423 |
4424 | offset = ptvc->offset;
4425 | 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", 4425, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4425, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4425, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4426 | get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
4427 | test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
4428 |
4429 | ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
4430 |
4431 | CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
4432 |
4433 | /* Coast clear. Try and fake it */
4434 | 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", 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];; 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", 4434, __func__, "Adding %s would put more than %d 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); } } };
4435 |
4436 | new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
4437 |
4438 | return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
4439 | offset, length, encoding);
4440 | }
4441 |
4442 | /* Add an item to a proto_tree, using the text label registered to that item;
4443 | the item is extracted from the tvbuff handed to it. */
4444 | proto_item *
4445 | proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
4446 | const int start, int length, const unsigned encoding)
4447 | {
4448 | field_info *new_fi;
4449 | int item_length;
4450 |
4451 | 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", 4451, "hfinfo != ((void*)0)", "Not passed hfi!"))));
4452 |
4453 | get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4454 | test_length(hfinfo, tvb, start, item_length, encoding);
4455 |
4456 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4457 |
4458 | 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", 4458 , __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", 4458, "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", 4458, "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", 4458, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4459 |
4460 | new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4461 |
4462 | return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4463 | }
4464 |
4465 | proto_item *
4466 | proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4467 | const int start, int length, const unsigned encoding)
4468 | {
4469 | register header_field_info *hfinfo;
4470 |
4471 | 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", 4471, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4471, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4471, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4472 | return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
4473 | }
4474 |
4475 | /* Add an item to a proto_tree, using the text label registered to that item;
4476 | the item is extracted from the tvbuff handed to it.
4477 |
4478 | Return the length of the item through the pointer. */
4479 | proto_item *
4480 | proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
4481 | tvbuff_t *tvb, const int start,
4482 | int length, const unsigned encoding,
4483 | int *lenretval)
4484 | {
4485 | field_info *new_fi;
4486 | int item_length;
4487 | proto_item *item;
4488 |
4489 | 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", 4489, "hfinfo != ((void*)0)", "Not passed hfi!"))));
4490 |
4491 | get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4492 | test_length(hfinfo, tvb, start, item_length, encoding);
4493 |
4494 | if (!tree) {
4495 | /*
4496 | * We need to get the correct item length here.
4497 | * That's normally done by proto_tree_new_item(),
4498 | * but we won't be calling it.
4499 | */
4500 | *lenretval = get_full_length(hfinfo, tvb, start, length,
4501 | item_length, encoding);
4502 | return NULL((void*)0);
4503 | }
4504 |
4505 | 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", 4512 , __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", 4512, "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", 4512, "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", 4512 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4506 | /*((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", 4512 , __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", 4512, "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", 4512, "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", 4512 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4507 | * 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", 4512 , __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", 4512, "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", 4512, "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", 4512 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4508 | * 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", 4512 , __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", 4512, "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", 4512, "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", 4512 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4509 | */((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", 4512 , __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", 4512, "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", 4512, "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", 4512 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { { *lenretval = get_full_length(hfinfo, tvb, start, length , item_length, encoding); }; return proto_tree_add_fake_node( tree, hfinfo); } } }
4510 | *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", 4512 , __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", 4512, "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", 4512, "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", 4512 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { { *lenretval = get_full_length(hfinfo, tvb, start, length , item_length, encoding); }; return proto_tree_add_fake_node( tree, hfinfo); } } }
4511 | 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", 4512 , __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", 4512, "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", 4512, "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", 4512 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { { *lenretval = get_full_length(hfinfo, tvb, start, length , item_length, encoding); }; return proto_tree_add_fake_node( tree, hfinfo); } } }
4512 | })((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", 4512 , __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", 4512, "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", 4512, "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", 4512 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { { *lenretval = get_full_length(hfinfo, tvb, start, length , item_length, encoding); }; return proto_tree_add_fake_node( tree, hfinfo); } } };
4513 |
4514 | new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4515 |
4516 | item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4517 | *lenretval = new_fi->length;
4518 | return item;
4519 | }
4520 |
4521 | proto_item *
4522 | proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4523 | const int start, int length,
4524 | const unsigned encoding, int *lenretval)
4525 | {
4526 | register header_field_info *hfinfo;
4527 |
4528 | 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", 4528, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4528, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4528, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4529 | return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, lenretval);
4530 | }
4531 |
4532 | /* which FT_ types can use proto_tree_add_bytes_item() */
4533 | static inline bool_Bool
4534 | validate_proto_tree_add_bytes_ftype(const enum ftenum type)
4535 | {
4536 | return (type == FT_BYTES ||
4537 | type == FT_UINT_BYTES ||
4538 | type == FT_OID ||
4539 | type == FT_REL_OID ||
4540 | type == FT_SYSTEM_ID );
4541 | }
4542 |
4543 | /* Note: this does no validation that the byte array of an FT_OID or
4544 | FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
4545 | so I think it's ok to continue not validating it?
4546 | */
4547 | proto_item *
4548 | proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4549 | const unsigned start, unsigned length,
4550 | const unsigned encoding,
4551 | GByteArray *retval, unsigned *endoff, int *err)
4552 | {
4553 | field_info *new_fi;
4554 | GByteArray *bytes = retval;
4555 | GByteArray *created_bytes = NULL((void*)0);
4556 | bool_Bool failed = false0;
4557 | uint32_t n = 0;
4558 | header_field_info *hfinfo;
4559 | bool_Bool generate = (bytes || tree) ? true1 : false0;
4560 |
4561 | 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", 4561, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4561, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4561, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4562 |
4563 | 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", 4563, "hfinfo != ((void*)0)", "Not passed hfi!"))));
4564 |
4565 | 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", 4566, "validate_proto_tree_add_bytes_ftype(hfinfo->type)" , "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type" ))))
4566 | "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", 4566, "validate_proto_tree_add_bytes_ftype(hfinfo->type)" , "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type" ))));
4567 |
4568 | if (length == 0) {
4569 | return NULL((void*)0);
4570 | }
4571 |
4572 | if (encoding & ENC_STR_NUM0x01000000) {
4573 | 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" );
4574 | }
4575 |
4576 | if (generate && (encoding & ENC_STR_HEX0x02000000)) {
4577 | if (hfinfo->type == FT_UINT_BYTES) {
4578 | /* can't decode FT_UINT_BYTES from strings */
4579 | 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")
4580 | "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");
4581 | }
4582 |
4583 | unsigned hex_encoding = encoding;
4584 | if (!(encoding & ENC_SEP_MASK0x001F0000)) {
4585 | /* If none of the separator values are used,
4586 | * assume no separator (the common case). */
4587 | hex_encoding |= ENC_SEP_NONE0x00010000;
4588 | #if 0
4589 | 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")
4590 | "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");
4591 | #endif
4592 | }
4593 |
4594 | if (!bytes) {
4595 | /* caller doesn't care about return value, but we need it to
4596 | call tvb_get_string_bytes() and set the tree later */
4597 | bytes = created_bytes = g_byte_array_new();
4598 | }
4599 |
4600 | /*
4601 | * bytes might be NULL after this, but can't add expert
4602 | * error until later; if it's NULL, just note that
4603 | * it failed.
4604 | */
4605 | bytes = tvb_get_string_bytes(tvb, start, length, hex_encoding, bytes, endoff);
4606 | if (bytes == NULL((void*)0))
4607 | failed = true1;
4608 | }
4609 | else if (generate) {
4610 | tvb_ensure_bytes_exist(tvb, start, length);
4611 |
4612 | if (hfinfo->type == FT_UINT_BYTES) {
4613 | n = length; /* n is now the "header" length */
4614 | length = get_uint_value(tree, tvb, start, n, encoding);
4615 | /* length is now the value's length; only store the value in the array */
4616 | tvb_ensure_bytes_exist(tvb, start + n, length);
4617 | if (!bytes) {
4618 | /* caller doesn't care about return value, but
4619 | * we may need it to set the tree later */
4620 | bytes = created_bytes = g_byte_array_new();
4621 | }
4622 | g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
4623 | }
4624 | else if (length > 0) {
4625 | if (!bytes) {
4626 | /* caller doesn't care about return value, but
4627 | * we may need it to set the tree later */
4628 | bytes = created_bytes = g_byte_array_new();
4629 | }
4630 | g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
4631 | }
4632 |
4633 | if (endoff)
4634 | *endoff = start + n + length;
4635 | }
4636 |
4637 | if (err)
4638 | *err = failed ? EINVAL22 : 0;
4639 |
4640 | 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); }
4641 | {if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes , 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return ((void*)0); }
4642 | 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); }
4643 | 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); }
4644 | 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); }
4645 | bytes = NULL;if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes , 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return ((void*)0); }
4646 | } )if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes , 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return ((void*)0); };
4647 |
4648 | 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", 4654 , __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", 4654, "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", 4654, "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", 4654 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4649 | {((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", 4654 , __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", 4654, "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", 4654, "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", 4654 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4650 | 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", 4654 , __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", 4654, "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", 4654, "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", 4654 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4651 | 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", 4654 , __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", 4654, "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", 4654, "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", 4654 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4652 | 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", 4654 , __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", 4654, "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", 4654, "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", 4654 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { { if (created_bytes) g_byte_array_free(created_bytes, 1) ; created_bytes = ((void*)0); bytes = ((void*)0); }; return proto_tree_add_fake_node (tree, hfinfo); } } }
4653 | 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", 4654 , __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", 4654, "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", 4654, "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", 4654 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { { if (created_bytes) g_byte_array_free(created_bytes, 1) ; created_bytes = ((void*)0); bytes = ((void*)0); }; return proto_tree_add_fake_node (tree, hfinfo); } } }
4654 | } )((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", 4654 , __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", 4654, "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", 4654, "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", 4654 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { { if (created_bytes) g_byte_array_free(created_bytes, 1) ; created_bytes = ((void*)0); bytes = ((void*)0); }; return proto_tree_add_fake_node (tree, hfinfo); } } };
4655 |
4656 | /* n will be zero except when it's a FT_UINT_BYTES */
4657 | new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
4658 |
4659 | if (encoding & ENC_STRING0x07000000) {
4660 | if (failed)
4661 | expert_add_info(NULL((void*)0), tree, &ei_byte_array_string_decoding_failed_error);
4662 |
4663 | if (bytes)
4664 | proto_tree_set_bytes_gbytearray(new_fi, bytes);
4665 | else
4666 | proto_tree_set_bytes(new_fi, NULL((void*)0), 0);
4667 |
4668 | if (created_bytes)
4669 | g_byte_array_free(created_bytes, true1);
4670 | }
4671 | else {
4672 | /* n will be zero except when it's a FT_UINT_BYTES */
4673 | proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
4674 |
4675 | /* XXX: If we have a non-NULL tree but NULL retval, we don't
4676 | * use the byte array created above in this case.
4677 | */
4678 | if (created_bytes)
4679 | g_byte_array_free(created_bytes, true1);
4680 |
4681 | FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | (( encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while (0)
4682 | (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);
4683 | }
4684 |
4685 | return proto_tree_add_node(tree, new_fi);
4686 | }
4687 |
4688 |
4689 | proto_item *
4690 | proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4691 | const unsigned start, const unsigned length,
4692 | const unsigned encoding,
4693 | nstime_t *retval, unsigned *endoff, int *err)
4694 | {
4695 | field_info *new_fi;
4696 | nstime_t time_stamp;
4697 | int saved_err = 0;
4698 | header_field_info *hfinfo;
4699 |
4700 | 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", 4700, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4700, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4700, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4701 |
4702 | 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", 4702, "hfinfo != ((void*)0)", "Not passed hfi!"))));
4703 |
4704 | if (length == 0) {
4705 | if(retval) {
4706 | nstime_set_zero(retval);
4707 | }
4708 | return NULL((void*)0);
4709 | }
4710 |
4711 | nstime_set_zero(&time_stamp);
4712 |
4713 | if (encoding & ENC_STR_TIME_MASK0x001F0000) {
4714 | 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", 4714, ((hfinfo))->abbrev))));
4715 | /* The only string format that could be a relative time is
4716 | * ENC_ISO_8601_TIME, and that is treated as an absolute time
4717 | * relative to "now" currently.
4718 | */
4719 | if (!tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff))
4720 | saved_err = EINVAL22;
4721 | }
4722 | else {
4723 | 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", 4723, ((hfinfo))->abbrev))));
4724 | const bool_Bool is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? true1 : false0;
4725 |
4726 | tvb_ensure_bytes_exist(tvb, start, length);
4727 | get_time_value(tree, tvb, start, length, encoding, &time_stamp, is_relative);
4728 | if (endoff) *endoff = start + length;
4729 | }
4730 |
4731 | if (err) *err = saved_err;
4732 |
4733 | if (retval) {
4734 | retval->secs = time_stamp.secs;
4735 | retval->nsecs = time_stamp.nsecs;
4736 | }
4737 |
4738 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4739 |
4740 | 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", 4740 , __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", 4740, "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", 4740, "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", 4740, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4741 |
4742 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4743 |
4744 | proto_tree_set_time(new_fi, &time_stamp);
4745 |
4746 | if (encoding & ENC_STRING0x07000000) {
4747 | if (saved_err)
4748 | expert_add_info(NULL((void*)0), tree, &ei_date_time_string_decoding_failed_error);
4749 | }
4750 | else {
4751 | FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | (( encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while (0)
4752 | (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);
4753 | }
4754 |
4755 | return proto_tree_add_node(tree, new_fi);
4756 | }
4757 |
4758 | /* Add a FT_NONE to a proto_tree */
4759 | proto_item *
4760 | proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
4761 | const int start, int length, const char *format,
4762 | ...)
4763 | {
4764 | proto_item *pi;
4765 | va_list ap;
4766 | header_field_info *hfinfo;
4767 |
4768 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4769 |
4770 | 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", 4770 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4770, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4770, "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", 4770, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4771 |
4772 | 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", 4772 , ((hfinfo))->abbrev))));
4773 |
4774 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4775 |
4776 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 4776, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
4777 |
4778 | va_start(ap, format)__builtin_va_start(ap, format);
4779 | proto_tree_set_representation(pi, format, ap);
4780 | va_end(ap)__builtin_va_end(ap);
4781 |
4782 | /* no value to set for FT_NONE */
4783 | return pi;
4784 | }
4785 |
4786 | /* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
4787 | * offset, and returns proto_item* */
4788 | proto_item *
4789 | ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, int length,
4790 | const unsigned encoding)
4791 | {
4792 | proto_item *item;
4793 |
4794 | item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
4795 | length, encoding);
4796 |
4797 | return item;
4798 | }
4799 |
4800 | /* Advance the ptvcursor's offset within its tvbuff without
4801 | * adding anything to the proto_tree. */
4802 | void
4803 | ptvcursor_advance(ptvcursor_t* ptvc, unsigned length)
4804 | {
4805 | if (ckd_add(&ptvc->offset, ptvc->offset, length)__builtin_add_overflow((ptvc->offset), (length), (&ptvc ->offset))) {
4806 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
4807 | }
4808 | }
4809 |
4810 |
4811 | static void
4812 | proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length)
4813 | {
4814 | ws_assert(length >= 0)do { if ((1) && !(length >= 0)) ws_log_fatal_full( "Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4814, __func__, "assertion failed: %s" , "length >= 0"); } while (0);
4815 | fvalue_set_protocol(fi->value, tvb, field_data, (unsigned)length);
4816 | }
4817 |
4818 | /* Add a FT_PROTOCOL to a proto_tree */
4819 | proto_item *
4820 | proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4821 | int start, int length, const char *format, ...)
4822 | {
4823 | proto_item *pi;
4824 | field_info *new_fi;
4825 | tvbuff_t *protocol_tvb;
4826 | va_list ap;
4827 | header_field_info *hfinfo;
4828 | char* protocol_rep;
4829 |
4830 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4831 |
4832 | 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", 4832 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4832, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4832, "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", 4832, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4833 |
4834 | 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" , 4834, ((hfinfo))->abbrev))));
4835 |
4836 | /*
4837 | * This can throw an exception when it calls get_hfi_length before
4838 | * it allocates anything, if length is nonzero and start is past
4839 | * the end of the tvb. Afterwards it can't throw an exception,
4840 | * as length is clamped to the captured length remaining.
4841 | */
4842 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4843 | new_fi = PNODE_FINFO(pi)((pi)->finfo);
4844 | /* Start the protocol_tvb at the correct start offset, but allow it
4845 | * to be lengthened later via finfo_set_len. */
4846 | protocol_tvb = new_fi->ds_tvb ? tvb_new_subset_remaining(new_fi->ds_tvb, new_fi->start) : NULL((void*)0);
4847 |
4848 | va_start(ap, format)__builtin_va_start(ap, format);
4849 | protocol_rep = ws_strdup_vprintf(format, ap)wmem_strdup_vprintf(((void*)0), format, ap);
4850 | proto_tree_set_protocol_tvb(new_fi, protocol_tvb, protocol_rep, length);
4851 | g_free(protocol_rep)(__builtin_object_size ((protocol_rep), 0) != ((size_t) - 1)) ? g_free_sized (protocol_rep, __builtin_object_size ((protocol_rep ), 0)) : (g_free) (protocol_rep);
4852 | va_end(ap)__builtin_va_end(ap);
4853 |
4854 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 4854, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
4855 |
4856 | va_start(ap, format)__builtin_va_start(ap, format);
4857 | proto_tree_set_representation(pi, format, ap);
4858 | va_end(ap)__builtin_va_end(ap);
4859 |
4860 | return pi;
4861 | }
4862 |
4863 | /* Add a FT_BYTES to a proto_tree */
4864 | proto_item *
4865 | proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4866 | int length, const uint8_t *start_ptr)
4867 | {
4868 | proto_item *pi;
4869 | header_field_info *hfinfo;
4870 | int item_length;
4871 |
4872 | 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", 4872, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4872, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4872, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4873 | get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
4874 | test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4875 |
4876 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4877 |
4878 | 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", 4878 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4878, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4878, "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", 4878, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4879 |
4880 | 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", 4880, ((hfinfo))->abbrev))));
4881 |
4882 | if (start_ptr == NULL((void*)0) && tvb != NULL((void*)0))
4883 | start_ptr = tvb_get_ptr(tvb, start, length);
4884 |
4885 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4886 | proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, length);
4887 |
4888 | return pi;
4889 | }
4890 |
4891 | /* Add a FT_BYTES to a proto_tree */
4892 | proto_item *
4893 | proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4894 | int tvbuff_length, const uint8_t *start_ptr, int ptr_length)
4895 | {
4896 | proto_item *pi;
4897 | header_field_info *hfinfo;
4898 | int item_length;
4899 |
4900 | 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", 4900, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4900, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4900, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4901 | get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length, ENC_NA0x00000000);
4902 | test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4903 |
4904 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4905 |
4906 | 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", 4906 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4906, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4906, "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", 4906, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4907 |
4908 | 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", 4908, ((hfinfo))->abbrev))));
4909 |
4910 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
4911 | proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, ptr_length);
4912 |
4913 | return pi;
4914 | }
4915 |
4916 | proto_item *
4917 | proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4918 | int start, int length,
4919 | const uint8_t *start_ptr,
4920 | const char *format, ...)
4921 | {
4922 | proto_item *pi;
4923 | va_list ap;
4924 |
4925 | pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4926 |
4927 | 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; };
4928 |
4929 | va_start(ap, format)__builtin_va_start(ap, format);
4930 | proto_tree_set_representation_value(pi, format, ap);
4931 | va_end(ap)__builtin_va_end(ap);
4932 |
4933 | return pi;
4934 | }
4935 |
4936 | proto_item *
4937 | proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4938 | int start, int length, const uint8_t *start_ptr,
4939 | const char *format, ...)
4940 | {
4941 | proto_item *pi;
4942 | va_list ap;
4943 |
4944 | pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4945 |
4946 | 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; };
4947 |
4948 | va_start(ap, format)__builtin_va_start(ap, format);
4949 | proto_tree_set_representation(pi, format, ap);
4950 | va_end(ap)__builtin_va_end(ap);
4951 |
4952 | return pi;
4953 | }
4954 |
4955 | static void
4956 | proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length)
4957 | {
4958 | DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4958, "length >= 0" ))));
4959 | 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", 4959, "start_ptr != ((void*)0) || length == 0" ))));
4960 |
4961 | fvalue_set_bytes_data(fi->value, start_ptr, length);
4962 | }
4963 |
4964 |
4965 | static void
4966 | proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, int offset, int length)
4967 | {
4968 | tvb_ensure_bytes_exist(tvb, offset, length);
4969 | proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
4970 | }
4971 |
4972 | static void
4973 | proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
4974 | {
4975 | GByteArray *bytes;
4976 |
4977 | DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4977, "value != ((void*)0)" ))));
4978 |
4979 | bytes = byte_array_dup(value);
4980 |
4981 | fvalue_set_byte_array(fi->value, bytes);
4982 | }
4983 |
4984 | /* Add a FT_*TIME to a proto_tree */
4985 | proto_item *
4986 | proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4987 | int length, const nstime_t *value_ptr)
4988 | {
4989 | proto_item *pi;
4990 | header_field_info *hfinfo;
4991 |
4992 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4993 |
4994 | 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", 4994 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4994, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4994, "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", 4994, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4995 |
4996 | 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", 4996, ((hfinfo))->abbrev))));
4997 |
4998 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4999 | proto_tree_set_time(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5000 |
5001 | return pi;
5002 | }
5003 |
5004 | proto_item *
5005 | proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5006 | int start, int length, nstime_t *value_ptr,
5007 | const char *format, ...)
5008 | {
5009 | proto_item *pi;
5010 | va_list ap;
5011 |
5012 | pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
5013 | if (pi != tree) {
5014 | va_start(ap, format)__builtin_va_start(ap, format);
5015 | proto_tree_set_representation_value(pi, format, ap);
5016 | va_end(ap)__builtin_va_end(ap);
5017 | }
5018 |
5019 | return pi;
5020 | }
5021 |
5022 | proto_item *
5023 | proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5024 | int start, int length, nstime_t *value_ptr,
5025 | const char *format, ...)
5026 | {
5027 | proto_item *pi;
5028 | va_list ap;
5029 |
5030 | pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
5031 | if (pi != tree) {
5032 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5032, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5033 |
5034 | va_start(ap, format)__builtin_va_start(ap, format);
5035 | proto_tree_set_representation(pi, format, ap);
5036 | va_end(ap)__builtin_va_end(ap);
5037 | }
5038 |
5039 | return pi;
5040 | }
5041 |
5042 | /* Set the FT_*TIME value */
5043 | static void
5044 | proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
5045 | {
5046 | DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5046, "value_ptr != ((void*)0)" ))));
5047 |
5048 | fvalue_set_time(fi->value, value_ptr);
5049 | }
5050 |
5051 | /* Add a FT_IPXNET to a proto_tree */
5052 | proto_item *
5053 | proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5054 | int length, uint32_t value)
5055 | {
5056 | proto_item *pi;
5057 | header_field_info *hfinfo;
5058 |
5059 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5060 |
5061 | 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", 5061 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5061, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5061, "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", 5061, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5062 |
5063 | 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" , 5063, ((hfinfo))->abbrev))));
5064 |
5065 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5066 | proto_tree_set_ipxnet(PNODE_FINFO(pi)((pi)->finfo), value);
5067 |
5068 | return pi;
5069 | }
5070 |
5071 | proto_item *
5072 | proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5073 | int start, int length, uint32_t value,
5074 | const char *format, ...)
5075 | {
5076 | proto_item *pi;
5077 | va_list ap;
5078 |
5079 | pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5080 | if (pi != tree) {
5081 | va_start(ap, format)__builtin_va_start(ap, format);
5082 | proto_tree_set_representation_value(pi, format, ap);
5083 | va_end(ap)__builtin_va_end(ap);
5084 | }
5085 |
5086 | return pi;
5087 | }
5088 |
5089 | proto_item *
5090 | proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5091 | int start, int length, uint32_t value,
5092 | const char *format, ...)
5093 | {
5094 | proto_item *pi;
5095 | va_list ap;
5096 |
5097 | pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5098 | if (pi != tree) {
5099 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5099, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5100 |
5101 | va_start(ap, format)__builtin_va_start(ap, format);
5102 | proto_tree_set_representation(pi, format, ap);
5103 | va_end(ap)__builtin_va_end(ap);
5104 | }
5105 |
5106 | return pi;
5107 | }
5108 |
5109 | /* Set the FT_IPXNET value */
5110 | static void
5111 | proto_tree_set_ipxnet(field_info *fi, uint32_t value)
5112 | {
5113 | fvalue_set_uinteger(fi->value, value);
5114 | }
5115 |
5116 | /* Add a FT_IPv4 to a proto_tree */
5117 | proto_item *
5118 | proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5119 | int length, ws_in4_addr value)
5120 | {
5121 | proto_item *pi;
5122 | header_field_info *hfinfo;
5123 |
5124 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5125 |
5126 | 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", 5126 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5126, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5126, "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", 5126, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5127 |
5128 | 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", 5128 , ((hfinfo))->abbrev))));
5129 |
5130 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5131 | proto_tree_set_ipv4(PNODE_FINFO(pi)((pi)->finfo), value);
5132 |
5133 | return pi;
5134 | }
5135 |
5136 | proto_item *
5137 | proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5138 | int start, int length, ws_in4_addr value,
5139 | const char *format, ...)
5140 | {
5141 | proto_item *pi;
5142 | va_list ap;
5143 |
5144 | pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5145 | if (pi != tree) {
5146 | va_start(ap, format)__builtin_va_start(ap, format);
5147 | proto_tree_set_representation_value(pi, format, ap);
5148 | va_end(ap)__builtin_va_end(ap);
5149 | }
5150 |
5151 | return pi;
5152 | }
5153 |
5154 | proto_item *
5155 | proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5156 | int start, int length, ws_in4_addr value,
5157 | const char *format, ...)
5158 | {
5159 | proto_item *pi;
5160 | va_list ap;
5161 |
5162 | pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5163 | if (pi != tree) {
5164 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5164, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5165 |
5166 | va_start(ap, format)__builtin_va_start(ap, format);
5167 | proto_tree_set_representation(pi, format, ap);
5168 | va_end(ap)__builtin_va_end(ap);
5169 | }
5170 |
5171 | return pi;
5172 | }
5173 |
5174 | /* Set the FT_IPv4 value */
5175 | static void
5176 | proto_tree_set_ipv4(field_info *fi, ws_in4_addr value)
5177 | {
5178 | ipv4_addr_and_mask ipv4;
5179 | ws_ipv4_addr_and_mask_init(&ipv4, value, 32);
5180 | fvalue_set_ipv4(fi->value, &ipv4);
5181 | }
5182 |
5183 | /* Add a FT_IPv6 to a proto_tree */
5184 | proto_item *
5185 | proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5186 | int length, const ws_in6_addr *value)
5187 | {
5188 | proto_item *pi;
5189 | header_field_info *hfinfo;
5190 |
5191 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5192 |
5193 | 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", 5193 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5193, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5193, "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", 5193, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5194 |
5195 | 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", 5195 , ((hfinfo))->abbrev))));
5196 |
5197 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5198 | proto_tree_set_ipv6(PNODE_FINFO(pi)((pi)->finfo), value);
5199 |
5200 | return pi;
5201 | }
5202 |
5203 | proto_item *
5204 | proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5205 | int start, int length,
5206 | const ws_in6_addr *value_ptr,
5207 | const char *format, ...)
5208 | {
5209 | proto_item *pi;
5210 | va_list ap;
5211 |
5212 | pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5213 | if (pi != tree) {
5214 | va_start(ap, format)__builtin_va_start(ap, format);
5215 | proto_tree_set_representation_value(pi, format, ap);
5216 | va_end(ap)__builtin_va_end(ap);
5217 | }
5218 |
5219 | return pi;
5220 | }
5221 |
5222 | proto_item *
5223 | proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5224 | int start, int length,
5225 | const ws_in6_addr *value_ptr,
5226 | const char *format, ...)
5227 | {
5228 | proto_item *pi;
5229 | va_list ap;
5230 |
5231 | pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5232 | if (pi != tree) {
5233 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5233, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5234 |
5235 | va_start(ap, format)__builtin_va_start(ap, format);
5236 | proto_tree_set_representation(pi, format, ap);
5237 | va_end(ap)__builtin_va_end(ap);
5238 | }
5239 |
5240 | return pi;
5241 | }
5242 |
5243 | /* Set the FT_IPv6 value */
5244 | static void
5245 | proto_tree_set_ipv6(field_info *fi, const ws_in6_addr *value)
5246 | {
5247 | DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5247, "value != ((void*)0)" ))));
5248 | ipv6_addr_and_prefix ipv6;
5249 | ipv6.addr = *value;
5250 | ipv6.prefix = 128;
5251 | fvalue_set_ipv6(fi->value, &ipv6);
5252 | }
5253 |
5254 | static void
5255 | proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5256 | {
5257 | proto_tree_set_ipv6(fi, (const ws_in6_addr *)tvb_get_ptr(tvb, start, length));
5258 | }
5259 |
5260 | /* Set the FT_FCWWN value */
5261 | static void
5262 | proto_tree_set_fcwwn(field_info *fi, const uint8_t* value_ptr)
5263 | {
5264 | DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5264, "value_ptr != ((void*)0)" ))));
5265 | fvalue_set_fcwwn(fi->value, value_ptr);
5266 | }
5267 |
5268 | static void
5269 | proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5270 | {
5271 | proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
5272 | }
5273 |
5274 | /* Add a FT_GUID to a proto_tree */
5275 | proto_item *
5276 | proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5277 | int length, const e_guid_t *value_ptr)
5278 | {
5279 | proto_item *pi;
5280 | header_field_info *hfinfo;
5281 |
5282 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5283 |
5284 | 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", 5284 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5284, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5284, "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", 5284, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5285 |
5286 | 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", 5286 , ((hfinfo))->abbrev))));
5287 |
5288 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5289 | proto_tree_set_guid(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5290 |
5291 | return pi;
5292 | }
5293 |
5294 | proto_item *
5295 | proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5296 | int start, int length,
5297 | const e_guid_t *value_ptr,
5298 | const char *format, ...)
5299 | {
5300 | proto_item *pi;
5301 | va_list ap;
5302 |
5303 | pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5304 | if (pi != tree) {
5305 | va_start(ap, format)__builtin_va_start(ap, format);
5306 | proto_tree_set_representation_value(pi, format, ap);
5307 | va_end(ap)__builtin_va_end(ap);
5308 | }
5309 |
5310 | return pi;
5311 | }
5312 |
5313 | proto_item *
5314 | proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5315 | int start, int length, const e_guid_t *value_ptr,
5316 | const char *format, ...)
5317 | {
5318 | proto_item *pi;
5319 | va_list ap;
5320 |
5321 | pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5322 | if (pi != tree) {
5323 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5323, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5324 |
5325 | va_start(ap, format)__builtin_va_start(ap, format);
5326 | proto_tree_set_representation(pi, format, ap);
5327 | va_end(ap)__builtin_va_end(ap);
5328 | }
5329 |
5330 | return pi;
5331 | }
5332 |
5333 | /* Set the FT_GUID value */
5334 | static void
5335 | proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
5336 | {
5337 | DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5337, "value_ptr != ((void*)0)" ))));
5338 | fvalue_set_guid(fi->value, value_ptr);
5339 | }
5340 |
5341 | static void
5342 | proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, int start,
5343 | const unsigned encoding)
5344 | {
5345 | e_guid_t guid;
5346 |
5347 | tvb_get_guid(tvb, start, &guid, encoding);
5348 | proto_tree_set_guid(fi, &guid);
5349 | }
5350 |
5351 | /* Add a FT_OID to a proto_tree */
5352 | proto_item *
5353 | proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5354 | int length, const uint8_t* value_ptr)
5355 | {
5356 | proto_item *pi;
5357 | header_field_info *hfinfo;
5358 |
5359 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5360 |
5361 | 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", 5361 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5361, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5361, "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", 5361, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5362 |
5363 | 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", 5363 , ((hfinfo))->abbrev))));
5364 |
5365 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5366 | proto_tree_set_oid(PNODE_FINFO(pi)((pi)->finfo), value_ptr, length);
5367 |
5368 | return pi;
5369 | }
5370 |
5371 | proto_item *
5372 | proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5373 | int start, int length,
5374 | const uint8_t* value_ptr,
5375 | const char *format, ...)
5376 | {
5377 | proto_item *pi;
5378 | va_list ap;
5379 |
5380 | pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5381 | if (pi != tree) {
5382 | va_start(ap, format)__builtin_va_start(ap, format);
5383 | proto_tree_set_representation_value(pi, format, ap);
5384 | va_end(ap)__builtin_va_end(ap);
5385 | }
5386 |
5387 | return pi;
5388 | }
5389 |
5390 | proto_item *
5391 | proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5392 | int start, int length, const uint8_t* value_ptr,
5393 | const char *format, ...)
5394 | {
5395 | proto_item *pi;
5396 | va_list ap;
5397 |
5398 | pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5399 | if (pi != tree) {
5400 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5400, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5401 |
5402 | va_start(ap, format)__builtin_va_start(ap, format);
5403 | proto_tree_set_representation(pi, format, ap);
5404 | va_end(ap)__builtin_va_end(ap);
5405 | }
5406 |
5407 | return pi;
5408 | }
5409 |
5410 | /* Set the FT_OID value */
5411 | static void
5412 | proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, int length)
5413 | {
5414 | GByteArray *bytes;
5415 |
5416 | 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", 5416, "value_ptr != ((void*)0) || length == 0" ))));
5417 |
5418 | bytes = g_byte_array_new();
5419 | if (length > 0) {
5420 | g_byte_array_append(bytes, value_ptr, length);
5421 | }
5422 | fvalue_set_byte_array(fi->value, bytes);
5423 | }
5424 |
5425 | static void
5426 | proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5427 | {
5428 | proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
5429 | }
5430 |
5431 | /* Set the FT_SYSTEM_ID value */
5432 | static void
5433 | proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, int length)
5434 | {
5435 | GByteArray *bytes;
5436 |
5437 | 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", 5437, "value_ptr != ((void*)0) || length == 0" ))));
5438 |
5439 | bytes = g_byte_array_new();
5440 | if (length > 0) {
5441 | g_byte_array_append(bytes, value_ptr, length);
5442 | }
5443 | fvalue_set_byte_array(fi->value, bytes);
5444 | }
5445 |
5446 | static void
5447 | proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5448 | {
5449 | proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
5450 | }
5451 |
5452 | /* Add a FT_STRING, FT_STRINGZ, FT_STRINGZPAD, or FT_STRINGZTRUNC to a
5453 | * proto_tree. Creates own copy of string, and frees it when the proto_tree
5454 | * is destroyed. */
5455 | proto_item *
5456 | proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5457 | int length, const char* value)
5458 | {
5459 | proto_item *pi;
5460 | header_field_info *hfinfo;
5461 | int item_length;
5462 |
5463 | 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", 5463, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 5463, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5463, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
5464 | get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
5465 | /*
5466 | * Special case - if the length is 0, skip the test, so that
5467 | * we can have an empty string right after the end of the
5468 | * packet. (This handles URL-encoded forms where the last field
5469 | * has no value so the form ends right after the =.)
5470 | *
5471 | * XXX - length zero makes sense for FT_STRING, and more or less
5472 | * for FT_STRINGZTRUNC, and FT_STRINGZPAD, but doesn't make sense
5473 | * for FT_STRINGZ (except that a number of fields that should be
5474 | * one of the others are actually registered as FT_STRINGZ.)
5475 | */
5476 | if (item_length != 0)
5477 | test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
5478 |
5479 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5480 |
5481 | 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", 5481 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5481, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5481, "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", 5481, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5482 |
5483 | 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", 5483, ((hfinfo))->abbrev))));
5484 |
5485 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5486 | DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5486, "length >= 0" ))));
5487 |
5488 | 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", 5488, __func__, value, -1, __uni_endptr); } } while (0); } } while (0);
5489 | proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), value);
5490 |
5491 | return pi;
5492 | }
5493 |
5494 | proto_item *
5495 | proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5496 | int start, int length, const char* value,
5497 | const char *format,
5498 | ...)
5499 | {
5500 | proto_item *pi;
5501 | va_list ap;
5502 |
5503 | pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5504 | if (pi != tree) {
5505 | va_start(ap, format)__builtin_va_start(ap, format);
5506 | proto_tree_set_representation_value(pi, format, ap);
5507 | va_end(ap)__builtin_va_end(ap);
5508 | }
5509 |
5510 | return pi;
5511 | }
5512 |
5513 | proto_item *
5514 | proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5515 | int start, int length, const char* value,
5516 | const char *format, ...)
5517 | {
5518 | proto_item *pi;
5519 | va_list ap;
5520 |
5521 | pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5522 | if (pi != tree) {
5523 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5523, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5524 |
5525 | va_start(ap, format)__builtin_va_start(ap, format);
5526 | proto_tree_set_representation(pi, format, ap);
5527 | va_end(ap)__builtin_va_end(ap);
5528 | }
5529 |
5530 | return pi;
5531 | }
5532 |
5533 | /* Set the FT_STRING value */
5534 | static void
5535 | proto_tree_set_string(field_info *fi, const char* value)
5536 | {
5537 | if (value) {
5538 | fvalue_set_string(fi->value, value);
5539 | } else {
5540 | /*
5541 | * XXX - why is a null value for a string field
5542 | * considered valid?
5543 | */
5544 | fvalue_set_string(fi->value, "[ Null ]");
5545 | }
5546 | }
5547 |
5548 | /* Set the FT_AX25 value */
5549 | static void
5550 | proto_tree_set_ax25(field_info *fi, const uint8_t* value)
5551 | {
5552 | fvalue_set_ax25(fi->value, value);
5553 | }
5554 |
5555 | static void
5556 | proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, int start)
5557 | {
5558 | proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
5559 | }
5560 |
5561 | /* Set the FT_VINES value */
5562 | static void
5563 | proto_tree_set_vines(field_info *fi, const uint8_t* value)
5564 | {
5565 | fvalue_set_vines(fi->value, value);
5566 | }
5567 |
5568 | static void
5569 | proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, int start)
5570 | {
5571 | proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN6));
5572 | }
5573 |
5574 | /* Add a FT_ETHER to a proto_tree */
5575 | proto_item *
5576 | proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5577 | int length, const uint8_t* value)
5578 | {
5579 | proto_item *pi;
5580 | header_field_info *hfinfo;
5581 |
5582 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5583 |
5584 | 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", 5584 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5584, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5584, "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", 5584, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5585 |
5586 | 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", 5586, ((hfinfo))->abbrev))));
5587 |
5588 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5589 | proto_tree_set_ether(PNODE_FINFO(pi)((pi)->finfo), value);
5590 |
5591 | return pi;
5592 | }
5593 |
5594 | proto_item *
5595 | proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5596 | int start, int length, const uint8_t* value,
5597 | const char *format, ...)
5598 | {
5599 | proto_item *pi;
5600 | va_list ap;
5601 |
5602 | pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5603 | if (pi != tree) {
5604 | va_start(ap, format)__builtin_va_start(ap, format);
5605 | proto_tree_set_representation_value(pi, format, ap);
5606 | va_end(ap)__builtin_va_end(ap);
5607 | }
5608 |
5609 | return pi;
5610 | }
5611 |
5612 | proto_item *
5613 | proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5614 | int start, int length, const uint8_t* value,
5615 | const char *format, ...)
5616 | {
5617 | proto_item *pi;
5618 | va_list ap;
5619 |
5620 | pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5621 | if (pi != tree) {
5622 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5622, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5623 |
5624 | va_start(ap, format)__builtin_va_start(ap, format);
5625 | proto_tree_set_representation(pi, format, ap);
5626 | va_end(ap)__builtin_va_end(ap);
5627 | }
5628 |
5629 | return pi;
5630 | }
5631 |
5632 | /* Set the FT_ETHER value */
5633 | static void
5634 | proto_tree_set_ether(field_info *fi, const uint8_t* value)
5635 | {
5636 | fvalue_set_ether(fi->value, value);
5637 | }
5638 |
5639 | static void
5640 | proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, int start)
5641 | {
5642 | proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN6));
5643 | }
5644 |
5645 | /* Add a FT_BOOLEAN to a proto_tree */
5646 | proto_item *
5647 | proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5648 | int length, uint64_t value)
5649 | {
5650 | proto_item *pi;
5651 | header_field_info *hfinfo;
5652 |
5653 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5654 |
5655 | 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", 5655 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5655, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5655, "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", 5655, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5656 |
5657 | 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" , 5657, ((hfinfo))->abbrev))));
5658 |
5659 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5660 | proto_tree_set_boolean(PNODE_FINFO(pi)((pi)->finfo), value);
5661 |
5662 | return pi;
5663 | }
5664 |
5665 | proto_item *
5666 | proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
5667 | tvbuff_t *tvb, int start, int length,
5668 | uint64_t value, const char *format, ...)
5669 | {
5670 | proto_item *pi;
5671 | va_list ap;
5672 |
5673 | pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5674 | if (pi != tree) {
5675 | va_start(ap, format)__builtin_va_start(ap, format);
5676 | proto_tree_set_representation_value(pi, format, ap);
5677 | va_end(ap)__builtin_va_end(ap);
5678 | }
5679 |
5680 | return pi;
5681 | }
5682 |
5683 | proto_item *
5684 | proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5685 | int start, int length, uint64_t value,
5686 | const char *format, ...)
5687 | {
5688 | proto_item *pi;
5689 | va_list ap;
5690 |
5691 | pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5692 | if (pi != tree) {
5693 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5693, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5694 |
5695 | va_start(ap, format)__builtin_va_start(ap, format);
5696 | proto_tree_set_representation(pi, format, ap);
5697 | va_end(ap)__builtin_va_end(ap);
5698 | }
5699 |
5700 | return pi;
5701 | }
5702 |
5703 | /* Set the FT_BOOLEAN value */
5704 | static void
5705 | proto_tree_set_boolean(field_info *fi, uint64_t value)
5706 | {
5707 | proto_tree_set_uint64(fi, value);
5708 | }
5709 |
5710 | /* Generate, into "buf", a string showing the bits of a bitfield.
5711 | Return a pointer to the character after that string. */
5712 | static char *
5713 | other_decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5714 | {
5715 | int i = 0;
5716 | uint64_t bit;
5717 | char *p;
5718 |
5719 | p = buf;
5720 |
5721 | /* This is a devel error. It is safer to stop here. */
5722 | DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5722, "width >= 1" ))));
5723 |
5724 | bit = UINT64_C(1)1UL << (width - 1);
5725 | for (;;) {
5726 | if (mask & bit) {
5727 | /* This bit is part of the field. Show its value. */
5728 | if (val & bit)
5729 | *p++ = '1';
5730 | else
5731 | *p++ = '0';
5732 | } else {
5733 | /* This bit is not part of the field. */
5734 | *p++ = '.';
5735 | }
5736 | bit >>= 1;
5737 | i++;
5738 | if (i >= width)
5739 | break;
5740 | if (i % 4 == 0)
5741 | *p++ = ' ';
5742 | }
5743 | *p = '\0';
5744 | return p;
5745 | }
5746 |
5747 | static char *
5748 | decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5749 | {
5750 | char *p;
5751 |
5752 | p = other_decode_bitfield_value(buf, val, mask, width);
5753 | p = g_stpcpy(p, " = ");
5754 |
5755 | return p;
5756 | }
5757 |
5758 | static char *
5759 | other_decode_bitfield_varint_value(char *buf, uint64_t val, uint64_t mask, const int width)
5760 | {
5761 | int i = 0;
5762 | uint64_t bit;
5763 | char *p;
5764 |
5765 | p = buf;
5766 |
5767 | /* This is a devel error. It is safer to stop here. */
5768 | DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5768, "width >= 1" ))));
5769 |
5770 | bit = UINT64_C(1)1UL << (width - 1);
5771 | for (;;) {
5772 | if (((8-(i % 8)) != 8) && /* MSB is never used for value. */
5773 | (mask & bit)) {
5774 | /* This bit is part of the field. Show its value. */
5775 | if (val & bit)
5776 | *p++ = '1';
5777 | else
5778 | *p++ = '0';
5779 | } else {
5780 | /* This bit is not part of the field. */
5781 | *p++ = '.';
5782 | }
5783 | bit >>= 1;
5784 | i++;
5785 | if (i >= width)
5786 | break;
5787 | if (i % 4 == 0)
5788 | *p++ = ' ';
5789 | }
5790 |
5791 | *p = '\0';
5792 | return p;
5793 | }
5794 |
5795 | static char *
5796 | decode_bitfield_varint_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5797 | {
5798 | char *p;
5799 |
5800 | p = other_decode_bitfield_varint_value(buf, val, mask, width);
5801 | p = g_stpcpy(p, " = ");
5802 |
5803 | return p;
5804 | }
5805 |
5806 | /* Add a FT_FLOAT to a proto_tree */
5807 | proto_item *
5808 | proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5809 | int length, float value)
5810 | {
5811 | proto_item *pi;
5812 | header_field_info *hfinfo;
5813 |
5814 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5815 |
5816 | 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", 5816 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5816, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5816, "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", 5816, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5817 |
5818 | 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", 5818, ((hfinfo))->abbrev))));
5819 |
5820 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5821 | proto_tree_set_float(PNODE_FINFO(pi)((pi)->finfo), value);
5822 |
5823 | return pi;
5824 | }
5825 |
5826 | proto_item *
5827 | proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5828 | int start, int length, float value,
5829 | const char *format, ...)
5830 | {
5831 | proto_item *pi;
5832 | va_list ap;
5833 |
5834 | pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5835 | if (pi != tree) {
5836 | va_start(ap, format)__builtin_va_start(ap, format);
5837 | proto_tree_set_representation_value(pi, format, ap);
5838 | va_end(ap)__builtin_va_end(ap);
5839 | }
5840 |
5841 | return pi;
5842 | }
5843 |
5844 | proto_item *
5845 | proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5846 | int start, int length, float value,
5847 | const char *format, ...)
5848 | {
5849 | proto_item *pi;
5850 | va_list ap;
5851 |
5852 | pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5853 | if (pi != tree) {
5854 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5854, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5855 |
5856 | va_start(ap, format)__builtin_va_start(ap, format);
5857 | proto_tree_set_representation(pi, format, ap);
5858 | va_end(ap)__builtin_va_end(ap);
5859 | }
5860 |
5861 | return pi;
5862 | }
5863 |
5864 | /* Set the FT_FLOAT value */
5865 | static void
5866 | proto_tree_set_float(field_info *fi, float value)
5867 | {
5868 | fvalue_set_floating(fi->value, value);
5869 | }
5870 |
5871 | /* Add a FT_DOUBLE to a proto_tree */
5872 | proto_item *
5873 | proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5874 | int length, double value)
5875 | {
5876 | proto_item *pi;
5877 | header_field_info *hfinfo;
5878 |
5879 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5880 |
5881 | 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", 5881 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5881, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5881, "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", 5881, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5882 |
5883 | 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" , 5883, ((hfinfo))->abbrev))));
5884 |
5885 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5886 | proto_tree_set_double(PNODE_FINFO(pi)((pi)->finfo), value);
5887 |
5888 | return pi;
5889 | }
5890 |
5891 | proto_item *
5892 | proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5893 | int start, int length, double value,
5894 | const char *format, ...)
5895 | {
5896 | proto_item *pi;
5897 | va_list ap;
5898 |
5899 | pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5900 | if (pi != tree) {
5901 | va_start(ap, format)__builtin_va_start(ap, format);
5902 | proto_tree_set_representation_value(pi, format, ap);
5903 | va_end(ap)__builtin_va_end(ap);
5904 | }
5905 |
5906 | return pi;
5907 | }
5908 |
5909 | proto_item *
5910 | proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5911 | int start, int length, double value,
5912 | const char *format, ...)
5913 | {
5914 | proto_item *pi;
5915 | va_list ap;
5916 |
5917 | pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5918 | if (pi != tree) {
5919 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5919, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5920 |
5921 | va_start(ap, format)__builtin_va_start(ap, format);
5922 | proto_tree_set_representation(pi, format, ap);
5923 | va_end(ap)__builtin_va_end(ap);
5924 | }
5925 |
5926 | return pi;
5927 | }
5928 |
5929 | /* Set the FT_DOUBLE value */
5930 | static void
5931 | proto_tree_set_double(field_info *fi, double value)
5932 | {
5933 | fvalue_set_floating(fi->value, value);
5934 | }
5935 |
5936 | /* Add FT_CHAR or FT_UINT{8,16,24,32} to a proto_tree */
5937 | proto_item *
5938 | proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5939 | int length, uint32_t value)
5940 | {
5941 | proto_item *pi = NULL((void*)0);
5942 | header_field_info *hfinfo;
5943 |
5944 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5945 |
5946 | 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", 5946 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5946, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5946, "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", 5946, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5947 |
5948 | switch (hfinfo->type) {
5949 | case FT_CHAR:
5950 | case FT_UINT8:
5951 | case FT_UINT16:
5952 | case FT_UINT24:
5953 | case FT_UINT32:
5954 | case FT_FRAMENUM:
5955 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5956 | proto_tree_set_uint(PNODE_FINFO(pi)((pi)->finfo), value);
5957 | break;
5958 |
5959 | default:
5960 | 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)
5961 | 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);
5962 | }
5963 |
5964 | return pi;
5965 | }
5966 |
5967 | proto_item *
5968 | proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5969 | int start, int length, uint32_t value,
5970 | const char *format, ...)
5971 | {
5972 | proto_item *pi;
5973 | va_list ap;
5974 |
5975 | pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5976 | if (pi != tree) {
5977 | va_start(ap, format)__builtin_va_start(ap, format);
5978 | proto_tree_set_representation_value(pi, format, ap);
5979 | va_end(ap)__builtin_va_end(ap);
5980 | }
5981 |
5982 | return pi;
5983 | }
5984 |
5985 | proto_item *
5986 | proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5987 | int start, int length, uint32_t value,
5988 | const char *format, ...)
5989 | {
5990 | proto_item *pi;
5991 | va_list ap;
5992 |
5993 | pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5994 | if (pi != tree) {
5995 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5995, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5996 |
5997 | va_start(ap, format)__builtin_va_start(ap, format);
5998 | proto_tree_set_representation(pi, format, ap);
5999 | va_end(ap)__builtin_va_end(ap);
6000 | }
6001 |
6002 | return pi;
6003 | }
6004 |
6005 | /* Set the FT_UINT{8,16,24,32} value */
6006 | static void
6007 | proto_tree_set_uint(field_info *fi, uint32_t value)
6008 | {
6009 | const header_field_info *hfinfo;
6010 | uint32_t integer;
6011 |
6012 | hfinfo = fi->hfinfo;
6013 | integer = value;
6014 |
6015 | if (hfinfo->bitmask) {
6016 | /* Mask out irrelevant portions */
6017 | integer &= (uint32_t)(hfinfo->bitmask);
6018 |
6019 | /* Shift bits */
6020 | integer >>= hfinfo_bitshift(hfinfo);
6021 |
6022 | FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset (hfinfo)) & 63) << 5)); } while(0);
6023 | 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);
6024 | }
6025 |
6026 | fvalue_set_uinteger(fi->value, integer);
6027 | }
6028 |
6029 | /* Add FT_UINT{40,48,56,64} to a proto_tree */
6030 | proto_item *
6031 | proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6032 | int length, uint64_t value)
6033 | {
6034 | proto_item *pi = NULL((void*)0);
6035 | header_field_info *hfinfo;
6036 |
6037 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6038 |
6039 | 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", 6039 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6039, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6039, "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", 6039, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
6040 |
6041 | switch (hfinfo->type) {
6042 | case FT_UINT40:
6043 | case FT_UINT48:
6044 | case FT_UINT56:
6045 | case FT_UINT64:
6046 | case FT_FRAMENUM:
6047 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6048 | proto_tree_set_uint64(PNODE_FINFO(pi)((pi)->finfo), value);
6049 | break;
6050 |
6051 | default:
6052 | 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)
6053 | 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);
6054 | }
6055 |
6056 | return pi;
6057 | }
6058 |
6059 | proto_item *
6060 | proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6061 | int start, int length, uint64_t value,
6062 | const char *format, ...)
6063 | {
6064 | proto_item *pi;
6065 | va_list ap;
6066 |
6067 | pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6068 | if (pi != tree) {
6069 | va_start(ap, format)__builtin_va_start(ap, format);
6070 | proto_tree_set_representation_value(pi, format, ap);
6071 | va_end(ap)__builtin_va_end(ap);
6072 | }
6073 |
6074 | return pi;
6075 | }
6076 |
6077 | proto_item *
6078 | proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6079 | int start, int length, uint64_t value,
6080 | const char *format, ...)
6081 | {
6082 | proto_item *pi;
6083 | va_list ap;
6084 |
6085 | pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6086 | if (pi != tree) {
6087 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6087, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
6088 |
6089 | va_start(ap, format)__builtin_va_start(ap, format);
6090 | proto_tree_set_representation(pi, format, ap);
6091 | va_end(ap)__builtin_va_end(ap);
6092 | }
6093 |
6094 | return pi;
6095 | }
6096 |
6097 | /* Set the FT_UINT{40,48,56,64} value */
6098 | static void
6099 | proto_tree_set_uint64(field_info *fi, uint64_t value)
6100 | {
6101 | const header_field_info *hfinfo;
6102 | uint64_t integer;
6103 |
6104 | hfinfo = fi->hfinfo;
6105 | integer = value;
6106 |
6107 | if (hfinfo->bitmask) {
6108 | /* Mask out irrelevant portions */
6109 | integer &= hfinfo->bitmask;
6110 |
6111 | /* Shift bits */
6112 | integer >>= hfinfo_bitshift(hfinfo);
6113 |
6114 | FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset (hfinfo)) & 63) << 5)); } while(0);
6115 | 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);
6116 | }
6117 |
6118 | fvalue_set_uinteger64(fi->value, integer);
6119 | }
6120 |
6121 | /* Add FT_INT{8,16,24,32} to a proto_tree */
6122 | proto_item *
6123 | proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6124 | int length, int32_t value)
6125 | {
6126 | proto_item *pi = NULL((void*)0);
6127 | header_field_info *hfinfo;
6128 |
6129 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6130 |
6131 | 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", 6131 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6131, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6131, "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", 6131, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
6132 |
6133 | switch (hfinfo->type) {
6134 | case FT_INT8:
6135 | case FT_INT16:
6136 | case FT_INT24:
6137 | case FT_INT32:
6138 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6139 | proto_tree_set_int(PNODE_FINFO(pi)((pi)->finfo), value);
6140 | break;
6141 |
6142 | default:
6143 | 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)
6144 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32" , hfinfo->abbrev);
6145 | }
6146 |
6147 | return pi;
6148 | }
6149 |
6150 | proto_item *
6151 | proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6152 | int start, int length, int32_t value,
6153 | const char *format, ...)
6154 | {
6155 | proto_item *pi;
6156 | va_list ap;
6157 |
6158 | pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6159 | if (pi != tree) {
6160 | va_start(ap, format)__builtin_va_start(ap, format);
6161 | proto_tree_set_representation_value(pi, format, ap);
6162 | va_end(ap)__builtin_va_end(ap);
6163 | }
6164 |
6165 | return pi;
6166 | }
6167 |
6168 | proto_item *
6169 | proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6170 | int start, int length, int32_t value,
6171 | const char *format, ...)
6172 | {
6173 | proto_item *pi;
6174 | va_list ap;
6175 |
6176 | pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6177 | if (pi != tree) {
6178 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6178, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
6179 |
6180 | va_start(ap, format)__builtin_va_start(ap, format);
6181 | proto_tree_set_representation(pi, format, ap);
6182 | va_end(ap)__builtin_va_end(ap);
6183 | }
6184 |
6185 | return pi;
6186 | }
6187 |
6188 | /* Set the FT_INT{8,16,24,32} value */
6189 | static void
6190 | proto_tree_set_int(field_info *fi, int32_t value)
6191 | {
6192 | const header_field_info *hfinfo;
6193 | uint32_t integer;
6194 | int no_of_bits;
6195 |
6196 | hfinfo = fi->hfinfo;
6197 | integer = (uint32_t) value;
6198 |
6199 | if (hfinfo->bitmask) {
6200 | /* Mask out irrelevant portions */
6201 | integer &= (uint32_t)(hfinfo->bitmask);
6202 |
6203 | /* Shift bits */
6204 | integer >>= hfinfo_bitshift(hfinfo);
6205 |
6206 | no_of_bits = ws_count_ones(hfinfo->bitmask);
6207 | integer = ws_sign_ext32(integer, no_of_bits);
6208 |
6209 | FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset (hfinfo)) & 63) << 5)); } while(0);
6210 | 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);
6211 | }
6212 |
6213 | fvalue_set_sinteger(fi->value, integer);
6214 | }
6215 |
6216 | /* Add FT_INT{40,48,56,64} to a proto_tree */
6217 | proto_item *
6218 | proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6219 | int length, int64_t value)
6220 | {
6221 | proto_item *pi = NULL((void*)0);
6222 | header_field_info *hfinfo;
6223 |
6224 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6225 |
6226 | 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", 6226 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6226, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6226, "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", 6226, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
6227 |
6228 | switch (hfinfo->type) {
6229 | case FT_INT40:
6230 | case FT_INT48:
6231 | case FT_INT56:
6232 | case FT_INT64:
6233 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6234 | proto_tree_set_int64(PNODE_FINFO(pi)((pi)->finfo), value);
6235 | break;
6236 |
6237 | default:
6238 | 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)
6239 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64" , hfinfo->abbrev);
6240 | }
6241 |
6242 | return pi;
6243 | }
6244 |
6245 | proto_item *
6246 | proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6247 | int start, int length, int64_t value,
6248 | const char *format, ...)
6249 | {
6250 | proto_item *pi;
6251 | va_list ap;
6252 |
6253 | pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6254 | if (pi != tree) {
6255 | va_start(ap, format)__builtin_va_start(ap, format);
6256 | proto_tree_set_representation_value(pi, format, ap);
6257 | va_end(ap)__builtin_va_end(ap);
6258 | }
6259 |
6260 | return pi;
6261 | }
6262 |
6263 | /* Set the FT_INT{40,48,56,64} value */
6264 | static void
6265 | proto_tree_set_int64(field_info *fi, int64_t value)
6266 | {
6267 | const header_field_info *hfinfo;
6268 | uint64_t integer;
6269 | int no_of_bits;
6270 |
6271 | hfinfo = fi->hfinfo;
6272 | integer = value;
6273 |
6274 | if (hfinfo->bitmask) {
6275 | /* Mask out irrelevant portions */
6276 | integer &= hfinfo->bitmask;
6277 |
6278 | /* Shift bits */
6279 | integer >>= hfinfo_bitshift(hfinfo);
6280 |
6281 | no_of_bits = ws_count_ones(hfinfo->bitmask);
6282 | integer = ws_sign_ext64(integer, no_of_bits);
6283 |
6284 | FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset (hfinfo)) & 63) << 5)); } while(0);
6285 | 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);
6286 | }
6287 |
6288 | fvalue_set_sinteger64(fi->value, integer);
6289 | }
6290 |
6291 | proto_item *
6292 | proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6293 | int start, int length, int64_t value,
6294 | const char *format, ...)
6295 | {
6296 | proto_item *pi;
6297 | va_list ap;
6298 |
6299 | pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6300 | if (pi != tree) {
6301 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6301, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
6302 |
6303 | va_start(ap, format)__builtin_va_start(ap, format);
6304 | proto_tree_set_representation(pi, format, ap);
6305 | va_end(ap)__builtin_va_end(ap);
6306 | }
6307 |
6308 | return pi;
6309 | }
6310 |
6311 | /* Add a FT_EUI64 to a proto_tree */
6312 | proto_item *
6313 | proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6314 | int length, const uint64_t value)
6315 | {
6316 | proto_item *pi;
6317 | header_field_info *hfinfo;
6318 |
6319 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6320 |
6321 | 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", 6321 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6321, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6321, "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", 6321, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
6322 |
6323 | 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", 6323, ((hfinfo))->abbrev))));
6324 |
6325 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6326 | proto_tree_set_eui64(PNODE_FINFO(pi)((pi)->finfo), value);
6327 |
6328 | return pi;
6329 | }
6330 |
6331 | proto_item *
6332 | proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6333 | int start, int length, const uint64_t value,
6334 | const char *format, ...)
6335 | {
6336 | proto_item *pi;
6337 | va_list ap;
6338 |
6339 | pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6340 | if (pi != tree) {
6341 | va_start(ap, format)__builtin_va_start(ap, format);
6342 | proto_tree_set_representation_value(pi, format, ap);
6343 | va_end(ap)__builtin_va_end(ap);
6344 | }
6345 |
6346 | return pi;
6347 | }
6348 |
6349 | proto_item *
6350 | proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6351 | int start, int length, const uint64_t value,
6352 | const char *format, ...)
6353 | {
6354 | proto_item *pi;
6355 | va_list ap;
6356 |
6357 | pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6358 | if (pi != tree) {
6359 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6359, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
6360 |
6361 | va_start(ap, format)__builtin_va_start(ap, format);
6362 | proto_tree_set_representation(pi, format, ap);
6363 | va_end(ap)__builtin_va_end(ap);
6364 | }
6365 |
6366 | return pi;
6367 | }
6368 |
6369 | /* Set the FT_EUI64 value */
6370 | static void
6371 | proto_tree_set_eui64(field_info *fi, const uint64_t value)
6372 | {
6373 | uint8_t v[FT_EUI64_LEN8];
6374 | phtonu64(v, value);
6375 | fvalue_set_bytes_data(fi->value, v, FT_EUI64_LEN8);
6376 | }
6377 |
6378 | static void
6379 | proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding)
6380 | {
6381 | if (encoding)
6382 | {
6383 | proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
6384 | } else {
6385 | proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
6386 | }
6387 | }
6388 |
6389 | proto_item *
6390 | proto_tree_add_mac48_detail(const mac_hf_list_t *list_specific,
6391 | const mac_hf_list_t *list_generic,
6392 | int idx, tvbuff_t *tvb,
6393 | proto_tree *tree, int offset)
6394 | {
6395 | uint8_t addr[6];
6396 | const char *addr_name = NULL((void*)0);
6397 | const char *oui_name = NULL((void*)0);
6398 | proto_item *addr_item = NULL((void*)0);
6399 | proto_tree *addr_tree = NULL((void*)0);
6400 | proto_item *ret_val = NULL((void*)0);
6401 |
6402 | if (tree == NULL((void*)0) || list_specific == NULL((void*)0)) {
6403 | return NULL((void*)0);
6404 | }
6405 |
6406 | /* Resolve what we can of the address */
6407 | tvb_memcpy(tvb, addr, offset, sizeof addr);
6408 | if (list_specific->hf_addr_resolved || (list_generic && list_generic->hf_addr_resolved)) {
6409 | addr_name = get_ether_name(addr);
6410 | }
6411 | if (list_specific->hf_oui_resolved || (list_generic && list_generic->hf_oui_resolved)) {
6412 | oui_name = get_manuf_name_if_known(addr, sizeof(addr));
6413 | }
6414 |
6415 | /* Add the item for the specific address type */
6416 | ret_val = proto_tree_add_item(tree, *list_specific->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6417 | if (idx >= 0) {
6418 | addr_tree = proto_item_add_subtree(ret_val, idx);
6419 | }
6420 | else {
6421 | addr_tree = tree;
6422 | }
6423 |
6424 | if (list_specific->hf_addr_resolved != NULL((void*)0)) {
6425 | addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_addr_resolved,
6426 | tvb, offset, 6, addr_name);
6427 | proto_item_set_generated(addr_item);
6428 | proto_item_set_hidden(addr_item);
6429 | }
6430 |
6431 | if (list_specific->hf_oui != NULL((void*)0)) {
6432 | addr_item = proto_tree_add_item(addr_tree, *list_specific->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6433 | proto_item_set_generated(addr_item);
6434 | proto_item_set_hidden(addr_item);
6435 |
6436 | if (oui_name != NULL((void*)0) && list_specific->hf_oui_resolved != NULL((void*)0)) {
6437 | addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_oui_resolved, tvb, offset, 6, oui_name);
6438 | proto_item_set_generated(addr_item);
6439 | proto_item_set_hidden(addr_item);
6440 | }
6441 | }
6442 |
6443 | if (list_specific->hf_lg != NULL((void*)0)) {
6444 | proto_tree_add_item(addr_tree, *list_specific->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6445 | }
6446 | if (list_specific->hf_ig != NULL((void*)0)) {
6447 | proto_tree_add_item(addr_tree, *list_specific->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6448 | }
6449 |
6450 | /* Were we given a list for generic address fields? If not, stop here */
6451 | if (list_generic == NULL((void*)0)) {
6452 | return ret_val;
6453 | }
6454 |
6455 | addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6456 | proto_item_set_hidden(addr_item);
6457 |
6458 | if (list_generic->hf_addr_resolved != NULL((void*)0)) {
6459 | addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_addr_resolved,
6460 | tvb, offset, 6, addr_name);
6461 | proto_item_set_generated(addr_item);
6462 | proto_item_set_hidden(addr_item);
6463 | }
6464 |
6465 | if (list_generic->hf_oui != NULL((void*)0)) {
6466 | addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6467 | proto_item_set_generated(addr_item);
6468 | proto_item_set_hidden(addr_item);
6469 |
6470 | if (oui_name != NULL((void*)0) && list_generic->hf_oui_resolved != NULL((void*)0)) {
6471 | addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_oui_resolved, tvb, offset, 6, oui_name);
6472 | proto_item_set_generated(addr_item);
6473 | proto_item_set_hidden(addr_item);
6474 | }
6475 | }
6476 |
6477 | if (list_generic->hf_lg != NULL((void*)0)) {
6478 | addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6479 | proto_item_set_hidden(addr_item);
6480 | }
6481 | if (list_generic->hf_ig != NULL((void*)0)) {
6482 | addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6483 | proto_item_set_hidden(addr_item);
6484 | }
6485 | return ret_val;
6486 | }
6487 |
6488 | static proto_item *
6489 | proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo)
6490 | {
6491 | proto_node *pnode, *tnode, *sibling;
6492 | field_info *tfi;
6493 | unsigned depth = 1;
6494 |
6495 | ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6495, __func__, "assertion failed: %s", "tree" ); } while (0);
6496 |
6497 | /*
6498 | * Restrict our depth. proto_tree_traverse_pre_order and
6499 | * proto_tree_traverse_post_order (and possibly others) are recursive
6500 | * so we need to be mindful of our stack size.
6501 | */
6502 | if (tree->first_child == NULL((void*)0)) {
6503 | for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6504 | depth++;
6505 | if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6506 | 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__)), 6509)))
6507 | "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__)), 6509)))
6508 | 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__)), 6509)))
6509 | 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__)), 6509)));
6510 | }
6511 | }
6512 | }
6513 |
6514 | /*
6515 | * Make sure "tree" is ready to have subtrees under it, by
6516 | * checking whether it's been given an ett_ value.
6517 | *
6518 | * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6519 | * node of the protocol tree. That node is not displayed,
6520 | * so it doesn't need an ett_ value to remember whether it
6521 | * was expanded.
6522 | */
6523 | tnode = tree;
6524 | tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6525 | if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6526 | 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" , 6527)
6527 | 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" , 6527);
6528 | /* XXX - is it safe to continue here? */
6529 | }
6530 |
6531 | pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo-> pool)), sizeof(proto_node)));
6532 | PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = (( void*)0); pnode->next = ((void*)0);;
6533 | pnode->parent = tnode;
6534 | PNODE_HFINFO(pnode)((pnode)->hfinfo) = hfinfo;
6535 | PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0); // Faked
6536 | pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6537 |
6538 | if (tnode->last_child != NULL((void*)0)) {
6539 | sibling = tnode->last_child;
6540 | DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6540, "sibling->next == ((void*)0)" ))));
6541 | sibling->next = pnode;
6542 | } else
6543 | tnode->first_child = pnode;
6544 | tnode->last_child = pnode;
6545 |
6546 | /* We should not be adding a fake node for an interesting field */
6547 | 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", 6547, __func__, "assertion failed: %s" , "hfinfo->ref_type != HF_REF_TYPE_DIRECT && hfinfo->ref_type != HF_REF_TYPE_PRINT" ); } while (0);
6548 |
6549 | /* XXX - Should the proto_item have a header_field_info member, at least
6550 | * for faked items, to know what hfi was faked? (Some dissectors look at
6551 | * the tree items directly.)
6552 | */
6553 | return (proto_item *)pnode;
6554 | }
6555 |
6556 | /* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
6557 | static proto_item *
6558 | proto_tree_add_node(proto_tree *tree, field_info *fi)
6559 | {
6560 | proto_node *pnode, *tnode, *sibling;
6561 | field_info *tfi;
6562 | unsigned depth = 1;
6563 |
6564 | ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6564, __func__, "assertion failed: %s", "tree" ); } while (0);
6565 |
6566 | /*
6567 | * Restrict our depth. proto_tree_traverse_pre_order and
6568 | * proto_tree_traverse_post_order (and possibly others) are recursive
6569 | * so we need to be mindful of our stack size.
6570 | */
6571 | if (tree->first_child == NULL((void*)0)) {
6572 | for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6573 | depth++;
6574 | if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6575 | fvalue_free(fi->value);
6576 | fi->value = NULL((void*)0);
6577 | 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__)), 6580)))
6578 | "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__)), 6580)))
6579 | 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__)), 6580)))
6580 | 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__)), 6580)));
6581 | }
6582 | }
6583 | }
6584 |
6585 | /*
6586 | * Make sure "tree" is ready to have subtrees under it, by
6587 | * checking whether it's been given an ett_ value.
6588 | *
6589 | * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6590 | * node of the protocol tree. That node is not displayed,
6591 | * so it doesn't need an ett_ value to remember whether it
6592 | * was expanded.
6593 | */
6594 | tnode = tree;
6595 | tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6596 | if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6597 | /* Since we are not adding fi to a node, its fvalue won't get
6598 | * freed by proto_tree_free_node(), so free it now.
6599 | */
6600 | fvalue_free(fi->value);
6601 | fi->value = NULL((void*)0);
6602 | 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", 6603)
6603 | 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", 6603);
6604 | /* XXX - is it safe to continue here? */
6605 | }
6606 |
6607 | pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo-> pool)), sizeof(proto_node)));
6608 | PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = (( void*)0); pnode->next = ((void*)0);;
6609 | pnode->parent = tnode;
6610 | PNODE_HFINFO(pnode)((pnode)->hfinfo) = fi->hfinfo;
6611 | PNODE_FINFO(pnode)((pnode)->finfo) = fi;
6612 | pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6613 |
6614 | if (tnode->last_child != NULL((void*)0)) {
6615 | sibling = tnode->last_child;
6616 | DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6616, "sibling->next == ((void*)0)" ))));
6617 | sibling->next = pnode;
6618 | } else
6619 | tnode->first_child = pnode;
6620 | tnode->last_child = pnode;
6621 |
6622 | tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
6623 |
6624 | return (proto_item *)pnode;
6625 | }
6626 |
6627 |
6628 | /* Generic way to allocate field_info and add to proto_tree.
6629 | * Sets *pfi to address of newly-allocated field_info struct */
6630 | static proto_item *
6631 | proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, int start,
6632 | int *length)
6633 | {
6634 | proto_item *pi;
6635 | field_info *fi;
6636 | int item_length;
6637 |
6638 | get_hfi_length(hfinfo, tvb, start, length, &item_length, ENC_NA0x00000000);
6639 | fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6640 | pi = proto_tree_add_node(tree, fi);
6641 |
6642 | return pi;
6643 | }
6644 |
6645 |
6646 | static void
6647 | get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start, int *length,
6648 | int *item_length, const unsigned encoding)
6649 | {
6650 | int length_remaining;
6651 |
6652 | /*
6653 | * We only allow a null tvbuff if the item has a zero length,
6654 | * i.e. if there's no data backing it.
6655 | */
6656 | 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", 6656, "tvb != ((void*)0) || *length == 0" ))));
6657 |
6658 | /*
6659 | * XXX - in some protocols, there are 32-bit unsigned length
6660 | * fields, so lengths in protocol tree and tvbuff routines
6661 | * should really be unsigned. We should have, for those
6662 | * field types for which "to the end of the tvbuff" makes sense,
6663 | * additional routines that take no length argument and
6664 | * add fields that run to the end of the tvbuff.
6665 | */
6666 | if (*length == -1) {
6667 | /*
6668 | * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING,
6669 | * FT_STRINGZPAD, and FT_STRINGZTRUNC fields, a length
6670 | * of -1 means "set the length to what remains in the
6671 | * tvbuff".
6672 | *
6673 | * The assumption is either that
6674 | *
6675 | * 1) the length of the item can only be determined
6676 | * by dissection (typically true of items with
6677 | * subitems, which are probably FT_NONE or
6678 | * FT_PROTOCOL)
6679 | *
6680 | * or
6681 | *
6682 | * 2) if the tvbuff is "short" (either due to a short
6683 | * snapshot length or due to lack of reassembly of
6684 | * fragments/segments/whatever), we want to display
6685 | * what's available in the field (probably FT_BYTES
6686 | * or FT_STRING) and then throw an exception later
6687 | *
6688 | * or
6689 | *
6690 | * 3) the field is defined to be "what's left in the
6691 | * packet"
6692 | *
6693 | * so we set the length to what remains in the tvbuff so
6694 | * that, if we throw an exception while dissecting, it
6695 | * has what is probably the right value.
6696 | *
6697 | * For FT_STRINGZ, it means "the string is null-terminated,
6698 | * not null-padded; set the length to the actual length
6699 | * of the string", and if the tvbuff if short, we just
6700 | * throw an exception.
6701 | *
6702 | * For ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC|ENC_VARIANT_ZIGZAG|ENC_VARINT_SDNV,
6703 | * it means "find the end of the string",
6704 | * and if the tvbuff if short, we just throw an exception.
6705 | *
6706 | * It's not valid for any other type of field. For those
6707 | * fields, we treat -1 the same way we treat other
6708 | * negative values - we assume the length is a Really
6709 | * Big Positive Number, and throw a ReportedBoundsError
6710 | * exception, under the assumption that the Really Big
6711 | * Length would run past the end of the packet.
6712 | */
6713 | 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 )))) {
6714 | if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
6715 | /*
6716 | * Leave the length as -1, so our caller knows
6717 | * it was -1.
6718 | */
6719 | *item_length = *length;
6720 | return;
6721 | } else if (encoding & ENC_VARINT_QUIC0x00000004) {
6722 | switch (tvb_get_uint8(tvb, start) >> 6)
6723 | {
6724 | case 0: /* 0b00 => 1 byte length (6 bits Usable) */
6725 | *item_length = 1;
6726 | break;
6727 | case 1: /* 0b01 => 2 bytes length (14 bits Usable) */
6728 | *item_length = 2;
6729 | break;
6730 | case 2: /* 0b10 => 4 bytes length (30 bits Usable) */
6731 | *item_length = 4;
6732 | break;
6733 | case 3: /* 0b11 => 8 bytes length (62 bits Usable) */
6734 | *item_length = 8;
6735 | break;
6736 | }
6737 | }
6738 | }
6739 |
6740 | switch (hfinfo->type) {
6741 |
6742 | case FT_PROTOCOL:
6743 | case FT_NONE:
6744 | case FT_BYTES:
6745 | case FT_STRING:
6746 | case FT_STRINGZPAD:
6747 | case FT_STRINGZTRUNC:
6748 | /*
6749 | * We allow FT_PROTOCOLs to be zero-length -
6750 | * for example, an ONC RPC NULL procedure has
6751 | * neither arguments nor reply, so the
6752 | * payload for that protocol is empty.
6753 | *
6754 | * We also allow the others to be zero-length -
6755 | * because that's the way the code has been for a
6756 | * long, long time.
6757 | *
6758 | * However, we want to ensure that the start
6759 | * offset is not *past* the byte past the end
6760 | * of the tvbuff: we throw an exception in that
6761 | * case.
6762 | */
6763 | *length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
6764 | DISSECTOR_ASSERT(*length >= 0)((void) ((*length >= 0) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6764, "*length >= 0" ))));
6765 | break;
6766 |
6767 | case FT_STRINGZ:
6768 | /*
6769 | * Leave the length as -1, so our caller knows
6770 | * it was -1.
6771 | */
6772 | break;
6773 |
6774 | default:
6775 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6776 | DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\"" , "epan/proto.c", 6776));
6777 | }
6778 | *item_length = *length;
6779 | } else {
6780 | if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6781 | /*
6782 | * These types are for interior nodes of the
6783 | * tree, and don't have data associated with
6784 | * them; if the length is negative (XXX - see
6785 | * above) or goes past the end of the tvbuff,
6786 | * cut it short at the end of the tvbuff.
6787 | * That way, if this field is selected in
6788 | * Wireshark, we don't highlight stuff past
6789 | * the end of the data.
6790 | *
6791 | * If we don't have a tvb, then length must be zero,
6792 | * per the DISSECTOR_ASSERT() above.
6793 | *
6794 | * If we do have a tvb, and the length requested is
6795 | * nonzero, we want to ensure that the start offset
6796 | * is not *past* the byte past the end of the tvbuff
6797 | * data: we throw an exception in that case as above.
6798 | */
6799 | if (tvb && *length) {
6800 | length_remaining = tvb_ensure_captured_length_remaining(tvb, start);
6801 | if (*length < 0 ||
6802 | (*length > 0 &&
6803 | (length_remaining < *length)))
6804 | *length = length_remaining;
6805 | }
6806 | }
6807 | *item_length = *length;
6808 | if (*item_length < 0) {
6809 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6810 | }
6811 | }
6812 | }
6813 |
6814 | static void
6815 | get_hfi_length_unsigned(header_field_info* hfinfo, tvbuff_t* tvb, const unsigned start, unsigned* length,
6816 | unsigned* item_length, const unsigned encoding _U___attribute__((unused)))
6817 | {
6818 | unsigned length_remaining;
6819 |
6820 | /*
6821 | * We only allow a null tvbuff if the item has a zero length,
6822 | * i.e. if there's no data backing it.
6823 | */
6824 | 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", 6824, "tvb != ((void*)0) || *length == 0" ))));
6825 |
6826 |
6827 | if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6828 | /*
6829 | * These types are for interior nodes of the
6830 | * tree, and don't have data associated with
6831 | * them; if the length is negative (XXX - see
6832 | * above) or goes past the end of the tvbuff,
6833 | * cut it short at the end of the tvbuff.
6834 | * That way, if this field is selected in
6835 | * Wireshark, we don't highlight stuff past
6836 | * the end of the data.
6837 | *
6838 | * If we don't have a tvb, then length must be zero,
6839 | * per the DISSECTOR_ASSERT() above.
6840 | *
6841 | * If we do have a tvb, and the length requested is
6842 | * nonzero, we want to ensure that the start offset
6843 | * is not *past* the byte past the end of the tvbuff
6844 | * data: we throw an exception in that case as above.
6845 | * (If the length requested is zero, then it's quite
6846 | * likely that the start offset is the byte past the
6847 | * end, but that's ok.)
6848 | */
6849 | if (tvb && *length) {
6850 | length_remaining = tvb_ensure_captured_length_remaining(tvb, start);
6851 | if (length_remaining < *length) {
6852 | *length = length_remaining;
6853 | }
6854 | }
6855 | }
6856 | *item_length = *length;
6857 | }
6858 |
6859 | static int
6860 | get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start,
6861 | int length, unsigned item_length, const int encoding)
6862 | {
6863 | uint32_t n;
6864 |
6865 | /*
6866 | * We need to get the correct item length here.
6867 | * That's normally done by proto_tree_new_item(),
6868 | * but we won't be calling it.
6869 | */
6870 | switch (hfinfo->type) {
6871 |
6872 | case FT_NONE:
6873 | case FT_PROTOCOL:
6874 | case FT_BYTES:
6875 | /*
6876 | * The length is the specified length.
6877 | */
6878 | break;
6879 |
6880 | case FT_UINT_BYTES:
6881 | n = get_uint_value(NULL((void*)0), tvb, start, length, encoding);
6882 | item_length += n;
6883 | if ((int)item_length < length) {
6884 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6885 | }
6886 | break;
6887 |
6888 | /* XXX - make these just FT_UINT? */
6889 | case FT_UINT8:
6890 | case FT_UINT16:
6891 | case FT_UINT24:
6892 | case FT_UINT32:
6893 | case FT_UINT40:
6894 | case FT_UINT48:
6895 | case FT_UINT56:
6896 | case FT_UINT64:
6897 | /* XXX - make these just FT_INT? */
6898 | case FT_INT8:
6899 | case FT_INT16:
6900 | case FT_INT24:
6901 | case FT_INT32:
6902 | case FT_INT40:
6903 | case FT_INT48:
6904 | case FT_INT56:
6905 | case FT_INT64:
6906 | if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
6907 | if (length < -1) {
6908 | report_type_length_mismatch(NULL((void*)0), "a FT_[U]INT", length, true1);
6909 | }
6910 | if (length == -1) {
6911 | uint64_t dummy;
6912 | /* This can throw an exception */
6913 | /* XXX - do this without fetching the varint? */
6914 | length = tvb_get_varint(tvb, start, FT_VARINT_MAX_LEN10, &dummy, encoding);
6915 | if (length == 0) {
6916 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6917 | }
6918 | }
6919 | item_length = length;
6920 | break;
6921 | }
6922 |
6923 | /*
6924 | * The length is the specified length.
6925 | */
6926 | break;
6927 |
6928 | case FT_BOOLEAN:
6929 | case FT_CHAR:
6930 | case FT_IPv4:
6931 | case FT_IPXNET:
6932 | case FT_IPv6:
6933 | case FT_FCWWN:
6934 | case FT_AX25:
6935 | case FT_VINES:
6936 | case FT_ETHER:
6937 | case FT_EUI64:
6938 | case FT_GUID:
6939 | case FT_OID:
6940 | case FT_REL_OID:
6941 | case FT_SYSTEM_ID:
6942 | case FT_FLOAT:
6943 | case FT_DOUBLE:
6944 | case FT_STRING:
6945 | /*
6946 | * The length is the specified length.
6947 | */
6948 | break;
6949 |
6950 | case FT_STRINGZ:
6951 | if (length < -1) {
6952 | report_type_length_mismatch(NULL((void*)0), "a string", length, true1);
6953 | }
6954 | if (length == -1) {
6955 | /* This can throw an exception */
6956 | item_length = tvb_strsize_enc(tvb, start, encoding);
6957 | }
6958 | break;
6959 |
6960 | case FT_UINT_STRING:
6961 | n = get_uint_value(NULL((void*)0), tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
6962 | item_length += n;
6963 | if ((int)item_length < length) {
6964 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6965 | }
6966 | break;
6967 |
6968 | case FT_STRINGZPAD:
6969 | case FT_STRINGZTRUNC:
6970 | case FT_ABSOLUTE_TIME:
6971 | case FT_RELATIVE_TIME:
6972 | case FT_IEEE_11073_SFLOAT:
6973 | case FT_IEEE_11073_FLOAT:
6974 | /*
6975 | * The length is the specified length.
6976 | */
6977 | break;
6978 |
6979 | default:
6980 | 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 ))
6981 | 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 ))
6982 | 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 ))
6983 | 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 ));
6984 | break;
6985 | }
6986 | return item_length;
6987 | }
6988 |
6989 | // This was arbitrarily chosen, but if you're adding 50K items to the tree
6990 | // without advancing the offset you should probably take a long, hard look
6991 | // at what you're doing.
6992 | // We *could* make this a configurable option, but I (Gerald) would like to
6993 | // avoid adding yet another nerd knob.
6994 | # define PROTO_TREE_MAX_IDLE50000 50000
6995 | static field_info *
6996 | new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
6997 | const int start, const int item_length)
6998 | {
6999 | field_info *fi;
7000 |
7001 | FIELD_INFO_NEW(PNODE_POOL(tree), fi)fi = ((field_info*)wmem_alloc((((tree)->tree_data->pinfo ->pool)), sizeof(field_info)));
7002 |
7003 | fi->hfinfo = hfinfo;
7004 | fi->start = start;
7005 | fi->start += (tvb)?tvb_raw_offset(tvb):0;
7006 | /* add the data source tvbuff */
7007 | fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL((void*)0);
7008 |
7009 | // If our start offset hasn't advanced after adding many items it probably
7010 | // means we're in a large or infinite loop.
7011 | if (fi->start > 0) {
7012 | if (fi->ds_tvb == PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb && fi->start <= PTREE_DATA(tree)((tree)->tree_data)->max_start) {
7013 | PTREE_DATA(tree)((tree)->tree_data)->start_idle_count++;
7014 | if (PTREE_DATA(tree)((tree)->tree_data)->start_idle_count > PROTO_TREE_MAX_IDLE50000) {
7015 | if (wireshark_abort_on_too_many_items) {
7016 | ws_error("Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop",ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7017 , __func__, "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop" , hfinfo->abbrev, 50000)
7017 | hfinfo->abbrev, PROTO_TREE_MAX_IDLE)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7017 , __func__, "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop" , hfinfo->abbrev, 50000);
7018 | }
7019 | /* PROTO_TREE_MAX_IDLE should be < pref.gui_max_tree_items,
7020 | * but if not, we should hit the max item error earlier,
7021 | * so we shouldn't need to reset the tree count to
7022 | * ensure that the exception handler can add the item. */
7023 | THROW_MESSAGE(DissectorError,except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data ->pinfo->pool), "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop" , hfinfo->abbrev, 50000)))
7024 | wmem_strdup_printf(PNODE_POOL(tree),except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data ->pinfo->pool), "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop" , hfinfo->abbrev, 50000)))
7025 | "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop",except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data ->pinfo->pool), "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop" , hfinfo->abbrev, 50000)))
7026 | hfinfo->abbrev, PROTO_TREE_MAX_IDLE))except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data ->pinfo->pool), "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop" , hfinfo->abbrev, 50000)));
7027 | }
7028 | } else {
7029 | PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb = fi->ds_tvb;
7030 | PTREE_DATA(tree)((tree)->tree_data)->max_start = fi->start;
7031 | PTREE_DATA(tree)((tree)->tree_data)->start_idle_count = 0;
7032 | }
7033 | }
7034 | fi->length = item_length;
7035 | fi->tree_type = -1;
7036 | fi->flags = 0;
7037 | if (!PTREE_DATA(tree)((tree)->tree_data)->visible) {
7038 | /* If the tree is not visible, set the item hidden, unless we
7039 | * need the representation or length and can't fake them.
7040 | */
7041 | if (hfinfo->ref_type != HF_REF_TYPE_PRINT && (hfinfo->type != FT_PROTOCOL || PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) {
7042 | FI_SET_FLAG(fi, FI_HIDDEN)do { if (fi) (fi)->flags = (fi)->flags | (0x00000001); } while(0);
7043 | }
7044 | }
7045 | fi->value = fvalue_new(fi->hfinfo->type);
7046 | fi->rep = NULL((void*)0);
7047 |
7048 | fi->appendix_start = 0;
7049 | fi->appendix_length = 0;
7050 |
7051 | fi->total_layer_num = tree->tree_data->pinfo->curr_layer_num;
7052 | fi->proto_layer_num = tree->tree_data->pinfo->curr_proto_layer_num;
7053 |
7054 | return fi;
7055 | }
7056 |
7057 | static size_t proto_find_value_pos(const header_field_info *hfinfo, const char *representation)
7058 | {
7059 | if (hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000) {
7060 | return 0;
7061 | }
7062 |
7063 | /* Search for field name */
7064 | char *ptr = strstr(representation, hfinfo->name);
7065 | if (!ptr) {
7066 | return 0;
7067 | }
7068 |
7069 | /* Check if field name ends with the ": " delimiter */
7070 | ptr += strlen(hfinfo->name);
7071 | if (strncmp(ptr, ": ", 2) == 0) {
7072 | ptr += 2;
7073 | }
7074 |
7075 | /* Return offset to after field name */
7076 | return ptr - representation;
7077 | }
7078 |
7079 | static size_t label_find_name_pos(const item_label_t *rep)
7080 | {
7081 | size_t name_pos = 0;
7082 |
7083 | /* If the value_pos is too small or too large, we can't find the expected format */
7084 | if (rep->value_pos <= 2 || rep->value_pos >= sizeof(rep->representation)) {
7085 | return 0;
7086 | }
7087 |
7088 | /* Check if the format looks like "label: value", then set name_pos before ':'. */
7089 | if (rep->representation[rep->value_pos-2] == ':') {
7090 | name_pos = rep->value_pos - 2;
7091 | }
7092 |
7093 | return name_pos;
7094 | }
7095 |
7096 | /* If the protocol tree is to be visible, set the representation of a
7097 | proto_tree entry with the name of the field for the item and with
7098 | the value formatted with the supplied printf-style format and
7099 | argument list. */
7100 | static void
7101 | proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
7102 | {
7103 | ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 7103, __func__, "assertion failed: %s", "pi" ); } while (0);
7104 |
7105 | /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
7106 | * items string representation */
7107 | if (PTREE_DATA(pi)((pi)->tree_data)->visible || !proto_item_is_hidden(pi)) {
7108 | size_t name_pos, ret = 0;
7109 | char *str;
7110 | field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7111 | const header_field_info *hf;
7112 |
7113 | DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 7113, "fi"))));
7114 |
7115 | hf = fi->hfinfo;
7116 |
7117 | 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;;
7118 | 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)))) {
7119 | uint64_t val;
7120 | char *p;
7121 |
7122 | 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))
7123 | val = fvalue_get_uinteger(fi->value);
7124 | else
7125 | val = fvalue_get_uinteger64(fi->value);
7126 |
7127 | val <<= hfinfo_bitshift(hf);
7128 |
7129 | p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
7130 | ret = (p - fi->rep->representation);
7131 | }
7132 |
7133 | /* put in the hf name */
7134 | 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);
7135 |
7136 | ret = label_concat(fi->rep->representation, ret, (const uint8_t*)": ")ws_label_strcpy(fi->rep->representation, 240, ret, (const uint8_t*)": ", 0);
7137 | /* If possible, Put in the value of the string */
7138 | str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7139 | 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" , 7139, __func__, str, -1, __uni_endptr); } } while (0); } } while (0);
7140 | fi->rep->value_pos = ret;
7141 | ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, ret, (const uint8_t*)str, 0);
7142 | if (ret >= ITEM_LABEL_LENGTH240) {
7143 | /* Uh oh, we don't have enough room. Tell the user
7144 | * that the field is truncated.
7145 | */
7146 | label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7147 | }
7148 | fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7149 | }
7150 | }
7151 |
7152 | /* If the protocol tree is to be visible, set the representation of a
7153 | proto_tree entry with the representation formatted with the supplied
7154 | printf-style format and argument list. */
7155 | static void
7156 | proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
7157 | {
7158 | size_t ret; /*tmp return value */
7159 | char *str;
7160 | field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7161 |
7162 | DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 7162, "fi"))));
7163 |
7164 | if (!proto_item_is_hidden(pi)) {
7165 | 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;;
7166 |
7167 | str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7168 | 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" , 7168, __func__, str, -1, __uni_endptr); } } while (0); } } while (0);
7169 | fi->rep->value_pos = proto_find_value_pos(fi->hfinfo, str);
7170 | ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, (const uint8_t*)str, 0);
7171 | if (ret >= ITEM_LABEL_LENGTH240) {
7172 | /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7173 | size_t name_pos = label_find_name_pos(fi->rep);
7174 | label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7175 | }
7176 | fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7177 | }
7178 | }
7179 |
7180 | static int
7181 | proto_strlcpy(char *dest, const char *src, size_t dest_size)
7182 | {
7183 | if (dest_size == 0) return 0;
7184 |
7185 | size_t res = g_strlcpy(dest, src, dest_size);
7186 |
7187 | /* At most dest_size - 1 characters will be copied
7188 | * (unless dest_size is 0). */
7189 | if (res >= dest_size)
7190 | res = dest_size - 1;
7191 | return (int) res;
7192 | }
7193 |
7194 | static header_field_info *
7195 | hfinfo_same_name_get_prev(const header_field_info *hfinfo)
7196 | {
7197 | header_field_info *dup_hfinfo;
7198 |
7199 | if (hfinfo->same_name_prev_id == -1)
7200 | return NULL((void*)0);
7201 | 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", 7201 , __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", 7201, "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", 7201, "gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)" , "Unregistered hf!")))) ; dup_hfinfo = gpa_hfinfo.hfi[hfinfo ->same_name_prev_id];;
7202 | return dup_hfinfo;
7203 | }
7204 |
7205 | static void
7206 | hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
7207 | {
7208 | g_free(last_field_name)(__builtin_object_size ((last_field_name), 0) != ((size_t) - 1 )) ? g_free_sized (last_field_name, __builtin_object_size ((last_field_name ), 0)) : (g_free) (last_field_name);
7209 | last_field_name = NULL((void*)0);
7210 |
7211 | if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
7212 | /* No hfinfo with the same name */
7213 | wmem_map_remove(gpa_name_map, hfinfo->abbrev);
7214 | return;
7215 | }
7216 |
7217 | if (hfinfo->same_name_next) {
7218 | hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
7219 | }
7220 |
7221 | if (hfinfo->same_name_prev_id != -1) {
7222 | header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
7223 | same_name_prev->same_name_next = hfinfo->same_name_next;
7224 | if (!hfinfo->same_name_next) {
7225 | /* It's always the latest added hfinfo which is stored in gpa_name_map */
7226 | wmem_map_insert(gpa_name_map, (void *) (same_name_prev->abbrev), same_name_prev);
7227 | }
7228 | }
7229 | }
7230 |
7231 | int
7232 | proto_item_fill_display_label(const field_info *finfo, char *display_label_str, const int label_str_size)
7233 | {
7234 | const header_field_info *hfinfo = finfo->hfinfo;
7235 | int label_len = 0;
7236 | char *tmp_str;
7237 | const char *str;
7238 | const uint8_t *bytes;
7239 | uint32_t number;
7240 | uint64_t number64;
7241 | const char *hf_str_val;
7242 | char number_buf[NUMBER_LABEL_LENGTH80];
7243 | const char *number_out;
7244 | address addr;
7245 | const ipv4_addr_and_mask *ipv4;
7246 | const ipv6_addr_and_prefix *ipv6;
7247 |
7248 | switch (hfinfo->type) {
7249 |
7250 | case FT_NONE:
7251 | case FT_PROTOCOL:
7252 | return proto_strlcpy(display_label_str, UTF8_CHECK_MARK"\u2713", label_str_size);
7253 |
7254 | case FT_UINT_BYTES:
7255 | case FT_BYTES:
7256 | tmp_str = format_bytes_hfinfo_maxlen(NULL((void*)0),
7257 | hfinfo,
7258 | fvalue_get_bytes_data(finfo->value),
7259 | (unsigned)fvalue_length2(finfo->value),
7260 | label_str_size);
7261 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7262 | wmem_free(NULL((void*)0), tmp_str);
7263 | break;
7264 |
7265 | case FT_ABSOLUTE_TIME:
7266 | {
7267 | const nstime_t *value = fvalue_get_time(finfo->value);
7268 | int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
7269 | if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_COLUMN) {
7270 | flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
7271 | }
7272 | if (hfinfo->strings) {
7273 | const char *time_string = try_time_val_to_str(value, (const time_value_string*)hfinfo->strings);
7274 | if (time_string != NULL((void*)0)) {
7275 | label_len = proto_strlcpy(display_label_str, time_string, label_str_size);
7276 | break;
7277 | }
7278 | }
7279 | tmp_str = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
7280 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7281 | wmem_free(NULL((void*)0), tmp_str);
7282 | break;
7283 | }
7284 |
7285 | case FT_RELATIVE_TIME:
7286 | tmp_str = rel_time_to_secs_str(NULL((void*)0), fvalue_get_time(finfo->value));
7287 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7288 | wmem_free(NULL((void*)0), tmp_str);
7289 | break;
7290 |
7291 | case FT_BOOLEAN:
7292 | number64 = fvalue_get_uinteger64(finfo->value);
7293 | label_len = proto_strlcpy(display_label_str,
7294 | tfs_get_string(!!number64, hfinfo->strings), label_str_size);
7295 | break;
7296 |
7297 | case FT_CHAR:
7298 | number = fvalue_get_uinteger(finfo->value);
7299 |
7300 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7301 | char tmp[ITEM_LABEL_LENGTH240];
7302 | custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7303 |
7304 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 7304, "fmtfunc"))));
7305 | fmtfunc(tmp, number);
7306 |
7307 | label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7308 |
7309 | } else if (hfinfo->strings) {
7310 | number_out = hf_try_val_to_str(number, hfinfo);
7311 |
7312 | if (!number_out) {
7313 | number_out = hfinfo_char_value_format_display(BASE_HEX, number_buf, number);
7314 | }
7315 |
7316 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7317 |
7318 | } else {
7319 | number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
7320 |
7321 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7322 | }
7323 |
7324 | break;
7325 |
7326 | /* XXX - make these just FT_NUMBER? */
7327 | case FT_INT8:
7328 | case FT_INT16:
7329 | case FT_INT24:
7330 | case FT_INT32:
7331 | case FT_UINT8:
7332 | case FT_UINT16:
7333 | case FT_UINT24:
7334 | case FT_UINT32:
7335 | case FT_FRAMENUM:
7336 | hf_str_val = NULL((void*)0);
7337 | 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 )) ?
7338 | (uint32_t) fvalue_get_sinteger(finfo->value) :
7339 | fvalue_get_uinteger(finfo->value);
7340 |
7341 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7342 | char tmp[ITEM_LABEL_LENGTH240];
7343 | custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7344 |
7345 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 7345, "fmtfunc"))));
7346 | fmtfunc(tmp, number);
7347 |
7348 | label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7349 |
7350 | } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
7351 | if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7352 | number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
7353 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7354 | hf_str_val = hf_try_val_to_str(number, hfinfo);
7355 | if (hf_str_val)
7356 | label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7357 | } else {
7358 | number_out = hf_try_val_to_str(number, hfinfo);
7359 |
7360 | if (!number_out) {
7361 | number_out = hfinfo_number_value_format_display(hfinfo, hfinfo->display, number_buf, number);
7362 | }
7363 |
7364 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7365 | }
7366 | } else {
7367 | number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
7368 |
7369 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7370 | }
7371 |
7372 | break;
7373 |
7374 | case FT_INT40:
7375 | case FT_INT48:
7376 | case FT_INT56:
7377 | case FT_INT64:
7378 | case FT_UINT40:
7379 | case FT_UINT48:
7380 | case FT_UINT56:
7381 | case FT_UINT64:
7382 | hf_str_val = NULL((void*)0);
7383 | 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 )) ?
7384 | (uint64_t) fvalue_get_sinteger64(finfo->value) :
7385 | fvalue_get_uinteger64(finfo->value);
7386 |
7387 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7388 | char tmp[ITEM_LABEL_LENGTH240];
7389 | custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
7390 |
7391 | DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug( "%s:%u: failed assertion \"%s\"", "epan/proto.c", 7391, "fmtfunc64" ))));
7392 | fmtfunc64(tmp, number64);
7393 |
7394 | label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7395 | } else if (hfinfo->strings) {
7396 | if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7397 | number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
7398 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7399 | hf_str_val = hf_try_val64_to_str(number64, hfinfo);
7400 | if (hf_str_val)
7401 | label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7402 | } else {
7403 | number_out = hf_try_val64_to_str(number64, hfinfo);
7404 |
7405 | if (!number_out)
7406 | number_out = hfinfo_number_value_format_display64(hfinfo, hfinfo->display, number_buf, number64);
7407 |
7408 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7409 | }
7410 | } else {
7411 | number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
7412 |
7413 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7414 | }
7415 |
7416 | break;
7417 |
7418 | case FT_EUI64:
7419 | set_address (&addr, AT_EUI64, EUI64_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7420 | tmp_str = address_to_display(NULL((void*)0), &addr);
7421 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7422 | wmem_free(NULL((void*)0), tmp_str);
7423 | break;
7424 |
7425 | case FT_IPv4:
7426 | ipv4 = fvalue_get_ipv4(finfo->value);
7427 | //XXX: Should we ignore the mask?
7428 | set_address_ipv4(&addr, ipv4);
7429 | tmp_str = address_to_display(NULL((void*)0), &addr);
7430 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7431 | wmem_free(NULL((void*)0), tmp_str);
7432 | free_address(&addr);
7433 | break;
7434 |
7435 | case FT_IPv6:
7436 | ipv6 = fvalue_get_ipv6(finfo->value);
7437 | set_address_ipv6(&addr, ipv6);
7438 | tmp_str = address_to_display(NULL((void*)0), &addr);
7439 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7440 | wmem_free(NULL((void*)0), tmp_str);
7441 | free_address(&addr);
7442 | break;
7443 |
7444 | case FT_FCWWN:
7445 | set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7446 | tmp_str = address_to_display(NULL((void*)0), &addr);
7447 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7448 | wmem_free(NULL((void*)0), tmp_str);
7449 | break;
7450 |
7451 | case FT_ETHER:
7452 | set_address (&addr, AT_ETHER, FT_ETHER_LEN6, fvalue_get_bytes_data(finfo->value));
7453 | tmp_str = address_to_display(NULL((void*)0), &addr);
7454 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7455 | wmem_free(NULL((void*)0), tmp_str);
7456 | break;
7457 |
7458 | case FT_GUID:
7459 | tmp_str = guid_to_str(NULL((void*)0), fvalue_get_guid(finfo->value));
7460 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7461 | wmem_free(NULL((void*)0), tmp_str);
7462 | break;
7463 |
7464 | case FT_REL_OID:
7465 | bytes = fvalue_get_bytes_data(finfo->value);
7466 | tmp_str = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7467 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7468 | wmem_free(NULL((void*)0), tmp_str);
7469 | break;
7470 |
7471 | case FT_OID:
7472 | bytes = fvalue_get_bytes_data(finfo->value);
7473 | tmp_str = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7474 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7475 | wmem_free(NULL((void*)0), tmp_str);
7476 | break;
7477 |
7478 | case FT_SYSTEM_ID:
7479 | bytes = fvalue_get_bytes_data(finfo->value);
7480 | tmp_str = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7481 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7482 | wmem_free(NULL((void*)0), tmp_str);
7483 | break;
7484 |
7485 | case FT_FLOAT:
7486 | case FT_DOUBLE:
7487 | label_len = (int)fill_display_label_float(finfo, display_label_str, label_str_size);
7488 | break;
7489 |
7490 | case FT_IEEE_11073_SFLOAT:
7491 | case FT_IEEE_11073_FLOAT:
7492 | label_len = (int)fill_display_label_ieee_11073_float(finfo, display_label_str, label_str_size);
7493 | break;
7494 |
7495 | case FT_STRING:
7496 | case FT_STRINGZ:
7497 | case FT_UINT_STRING:
7498 | case FT_STRINGZPAD:
7499 | case FT_STRINGZTRUNC:
7500 | str = fvalue_get_string(finfo->value);
7501 | label_len = (int)ws_label_strcpy(display_label_str, label_str_size, 0, (const uint8_t*)str, label_strcat_flags(hfinfo));
7502 | if (label_len >= label_str_size) {
7503 | /* Truncation occurred. Get the real length
7504 | * copied (not including '\0') */
7505 | label_len = label_str_size ? label_str_size - 1 : 0;
7506 | }
7507 | break;
7508 |
7509 | default:
7510 | /* First try ftype string representation */
7511 | tmp_str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DISPLAY, hfinfo->display);
7512 | if (!tmp_str) {
7513 | /* Default to show as bytes */
7514 | bytes = fvalue_get_bytes_data(finfo->value);
7515 | tmp_str = bytes_to_str(NULL, bytes, fvalue_length2(finfo->value))bytes_to_str_maxlen(((void*)0), bytes, fvalue_length2(finfo-> value), 36);
7516 | }
7517 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7518 | wmem_free(NULL((void*)0), tmp_str);
7519 | break;
7520 | }
7521 | return label_len;
7522 | }
7523 |
7524 | const char *
7525 | proto_custom_set(proto_tree* tree, GSList *field_ids, int occurrence, bool_Bool display_details,
7526 | char *result, char *expr, const int size)
7527 | {
7528 | int len, prev_len, last, i, offset_r = 0, offset_e = 0;
7529 | GPtrArray *finfos;
7530 | field_info *finfo = NULL((void*)0);
7531 | header_field_info* hfinfo;
7532 | const char *abbrev = NULL((void*)0);
7533 |
7534 | char *str;
7535 | col_custom_t *field_idx;
7536 | int field_id;
7537 | int ii = 0;
7538 |
7539 | ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7539, __func__, "assertion failed: %s" , "field_ids != ((void*)0)"); } while (0);
7540 | while ((field_idx = (col_custom_t *) g_slist_nth_data(field_ids, ii++))) {
7541 | field_id = field_idx->field_id;
7542 | if (field_id == 0) {
7543 | GPtrArray *fvals = NULL((void*)0);
7544 | bool_Bool passed = dfilter_apply_full(field_idx->dfilter, tree, &fvals);
7545 | if (fvals != NULL((void*)0)) {
7546 |
7547 | // XXX - Handling occurrences is unusual when more
7548 | // than one field is involved, e.g. there's four
7549 | // results for tcp.port + tcp.port. We may really
7550 | // want to apply it to the operands, not the output.
7551 | // Note that occurrences are not quite the same as
7552 | // the layer operator (should the grammar support
7553 | // both?)
7554 | /* Calculate single index or set outer boundaries */
7555 | len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7556 | if (occurrence < 0) {
7557 | i = occurrence + len;
7558 | last = i;
7559 | } else if (occurrence > 0) {
7560 | i = occurrence - 1;
7561 | last = i;
7562 | } else {
7563 | i = 0;
7564 | last = len - 1;
7565 | }
7566 | if (i < 0 || i >= len) {
7567 | g_ptr_array_unref(fvals);
7568 | continue;
7569 | }
7570 | for (; i <= last; i++) {
7571 | /* XXX - We could have a "resolved" result
7572 | * for types where the value depends only
7573 | * on the type, e.g. FT_IPv4, and not on
7574 | * hfinfo->strings. Supporting the latter
7575 | * requires knowing which hfinfo matched
7576 | * if there are multiple with the same
7577 | * abbreviation. In any case, we need to
7578 | * know the expected return type of the
7579 | * field expression.
7580 | */
7581 | str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DISPLAY, BASE_NONE);
7582 | if (offset_r && (offset_r < (size - 1)))
7583 | result[offset_r++] = ',';
7584 | if (offset_e && (offset_e < (size - 1)))
7585 | expr[offset_e++] = ',';
7586 | offset_r += proto_strlcpy(result+offset_r, str, size-offset_r);
7587 | // col_{add,append,set}_* calls ws_label_strcpy
7588 | offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7589 |
7590 | g_free(str)(__builtin_object_size ((str), 0) != ((size_t) - 1)) ? g_free_sized (str, __builtin_object_size ((str), 0)) : (g_free) (str);
7591 | }
7592 | g_ptr_array_unref(fvals);
7593 | } else if (passed) {
7594 | // XXX - Occurrence doesn't make sense for a test
7595 | // output, it should be applied to the operands.
7596 | if (offset_r && (offset_r < (size - 1)))
7597 | result[offset_r++] = ',';
7598 | if (offset_e && (offset_e < (size - 1)))
7599 | expr[offset_e++] = ',';
7600 | /* Prevent multiple check marks */
7601 | if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7602 | offset_r += proto_strlcpy(result+offset_r, UTF8_CHECK_MARK"\u2713", size-offset_r);
7603 | } else {
7604 | result[--offset_r] = '\0'; /* Remove the added trailing ',' */
7605 | }
7606 | if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7607 | offset_e += proto_strlcpy(expr+offset_e, UTF8_CHECK_MARK"\u2713", size-offset_e);
7608 | } else {
7609 | expr[--offset_e] = '\0'; /* Remove the added trailing ',' */
7610 | }
7611 | }
7612 | continue;
7613 | }
7614 | 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", 7614 , __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", 7614, "(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", 7614, "gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];;
7615 |
7616 | /* do we need to rewind ? */
7617 | if (!hfinfo)
7618 | return "";
7619 |
7620 | if (occurrence < 0) {
7621 | /* Search other direction */
7622 | while (hfinfo->same_name_prev_id != -1) {
7623 | 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", 7623 , __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", 7623, "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", 7623, "gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo-> same_name_prev_id];;
7624 | }
7625 | }
7626 |
7627 | prev_len = 0; /* Reset handled occurrences */
7628 |
7629 | while (hfinfo) {
7630 | finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
7631 |
7632 | if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7633 | if (occurrence < 0) {
7634 | hfinfo = hfinfo->same_name_next;
7635 | } else {
7636 | hfinfo = hfinfo_same_name_get_prev(hfinfo);
7637 | }
7638 | continue;
7639 | }
7640 |
7641 | /* Are there enough occurrences of the field? */
7642 | if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7643 | if (occurrence < 0) {
7644 | hfinfo = hfinfo->same_name_next;
7645 | } else {
7646 | hfinfo = hfinfo_same_name_get_prev(hfinfo);
7647 | }
7648 | prev_len += len;
7649 | continue;
7650 | }
7651 |
7652 | /* Calculate single index or set outer boundaries */
7653 | if (occurrence < 0) {
7654 | i = occurrence + len + prev_len;
7655 | last = i;
7656 | } else if (occurrence > 0) {
7657 | i = occurrence - 1 - prev_len;
7658 | last = i;
7659 | } else {
7660 | i = 0;
7661 | last = len - 1;
7662 | }
7663 |
7664 | prev_len += len; /* Count handled occurrences */
7665 |
7666 | while (i <= last) {
7667 | finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7668 |
7669 | if (offset_r && (offset_r < (size - 1)))
7670 | result[offset_r++] = ',';
7671 |
7672 | if (display_details) {
7673 | char representation[ITEM_LABEL_LENGTH240];
7674 | size_t offset = 0;
7675 |
7676 | if (finfo->rep && finfo->rep->value_len) {
7677 | (void) g_strlcpy(representation, &finfo->rep->representation[finfo->rep->value_pos],
7678 | MIN(finfo->rep->value_len + 1, ITEM_LABEL_LENGTH)(((finfo->rep->value_len + 1) < (240)) ? (finfo-> rep->value_len + 1) : (240)));
7679 | } else {
7680 | proto_item_fill_label(finfo, representation, &offset);
7681 | }
7682 | offset_r += proto_strlcpy(result+offset_r, &representation[offset], size-offset_r);
7683 | } else {
7684 | switch (hfinfo->type) {
7685 |
7686 | case FT_NONE:
7687 | case FT_PROTOCOL:
7688 | /* Prevent multiple check marks */
7689 | if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7690 | offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7691 | } else {
7692 | result[--offset_r] = '\0'; /* Remove the added trailing ',' again */
7693 | }
7694 | break;
7695 |
7696 | default:
7697 | offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7698 | break;
7699 | }
7700 | }
7701 |
7702 | if (offset_e && (offset_e < (size - 1)))
7703 | expr[offset_e++] = ',';
7704 |
7705 | 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 )))) {
7706 | const char *hf_str_val;
7707 | /* Integer types with BASE_NONE never get the numeric value. */
7708 | if (FT_IS_INT32(hfinfo->type)((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16 || (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32 )) {
7709 | hf_str_val = hf_try_val_to_str_const(fvalue_get_sinteger(finfo->value), hfinfo, "Unknown");
7710 | } 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 )) {
7711 | hf_str_val = hf_try_val_to_str_const(fvalue_get_uinteger(finfo->value), hfinfo, "Unknown");
7712 | } else if (FT_IS_INT64(hfinfo->type)((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48 || (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64 )) {
7713 | hf_str_val = hf_try_val64_to_str_const(fvalue_get_sinteger64(finfo->value), hfinfo, "Unknown");
7714 | } else { // if (FT_IS_UINT64(hfinfo->type)) {
7715 | hf_str_val = hf_try_val64_to_str_const(fvalue_get_uinteger64(finfo->value), hfinfo, "Unknown");
7716 | }
7717 | snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
7718 | offset_e = (int)strlen(expr);
7719 | } else if (hfinfo->type == FT_NONE || hfinfo->type == FT_PROTOCOL) {
7720 | /* Prevent multiple check marks */
7721 | if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7722 | offset_e += proto_item_fill_display_label(finfo, expr+offset_e, size-offset_e);
7723 | } else {
7724 | expr[--offset_e] = '\0'; /* Remove the added trailing ',' again */
7725 | }
7726 | } else {
7727 | str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_RAW, finfo->hfinfo->display);
7728 | // col_{add,append,set}_* calls ws_label_strcpy
7729 | offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7730 | wmem_free(NULL((void*)0), str);
7731 | }
7732 | i++;
7733 | }
7734 |
7735 | /* XXX: Why is only the first abbreviation returned for a multifield
7736 | * custom column? */
7737 | if (!abbrev) {
7738 | /* Store abbrev for return value */
7739 | abbrev = hfinfo->abbrev;
7740 | }
7741 |
7742 | if (occurrence == 0) {
7743 | /* Fetch next hfinfo with same name (abbrev) */
7744 | hfinfo = hfinfo_same_name_get_prev(hfinfo);
7745 | } else {
7746 | hfinfo = NULL((void*)0);
7747 | }
7748 | }
7749 | }
7750 |
7751 | if (offset_r >= (size - 1)) {
7752 | mark_truncated(result, 0, size, NULL((void*)0));
7753 | }
7754 | if (offset_e >= (size - 1)) {
7755 | mark_truncated(expr, 0, size, NULL((void*)0));
7756 | }
7757 | return abbrev ? abbrev : "";
7758 | }
7759 |
7760 | char *
7761 | proto_custom_get_filter(epan_dissect_t* edt, GSList *field_ids, int occurrence)
7762 | {
7763 | int len, prev_len, last, i;
7764 | GPtrArray *finfos;
7765 | field_info *finfo = NULL((void*)0);
7766 | header_field_info* hfinfo;
7767 |
7768 | char *filter = NULL((void*)0);
7769 | GPtrArray *filter_array;
7770 |
7771 | col_custom_t *col_custom;
7772 | int field_id;
7773 |
7774 | ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7774, __func__, "assertion failed: %s" , "field_ids != ((void*)0)"); } while (0);
7775 | filter_array = g_ptr_array_new_full(g_slist_length(field_ids), g_free);
7776 | for (GSList *iter = field_ids; iter; iter = iter->next) {
7777 | col_custom = (col_custom_t*)iter->data;
7778 | field_id = col_custom->field_id;
7779 | if (field_id == 0) {
7780 | GPtrArray *fvals = NULL((void*)0);
7781 | bool_Bool passed = dfilter_apply_full(col_custom->dfilter, edt->tree, &fvals);
7782 | if (fvals != NULL((void*)0)) {
7783 | // XXX - Handling occurrences is unusual when more
7784 | // than one field is involved, e.g. there's four
7785 | // results for tcp.port + tcp.port. We really
7786 | // want to apply it to the operands, not the output.
7787 | /* Calculate single index or set outer boundaries */
7788 | len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7789 | if (occurrence < 0) {
7790 | i = occurrence + len;
7791 | last = i;
7792 | } else if (occurrence > 0) {
7793 | i = occurrence - 1;
7794 | last = i;
7795 | } else {
7796 | i = 0;
7797 | last = len - 1;
7798 | }
7799 | if (i < 0 || i >= len) {
7800 | g_ptr_array_unref(fvals);
7801 | continue;
7802 | }
7803 | for (; i <= last; i++) {
7804 | /* XXX - Should multiple values for one
7805 | * field use set membership to reduce
7806 | * verbosity, here and below? */
7807 | char *str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DFILTER, BASE_NONE);
7808 | filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", col_custom->dftext, str);
7809 | wmem_free(NULL((void*)0), str);
7810 | if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7811 | g_ptr_array_add(filter_array, filter);
7812 | }
7813 | }
7814 | g_ptr_array_unref(fvals);
7815 | } else if (passed) {
7816 | filter = wmem_strdup(NULL((void*)0), col_custom->dftext);
7817 | if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7818 | g_ptr_array_add(filter_array, filter);
7819 | }
7820 | } else {
7821 | filter = wmem_strdup_printf(NULL((void*)0), "!(%s)", col_custom->dftext);
7822 | if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7823 | g_ptr_array_add(filter_array, filter);
7824 | }
7825 | }
7826 | continue;
7827 | }
7828 |
7829 | 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", 7829 , __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", 7829, "(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", 7829, "gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];;
7830 |
7831 | /* do we need to rewind ? */
7832 | if (!hfinfo)
7833 | return NULL((void*)0);
7834 |
7835 | if (occurrence < 0) {
7836 | /* Search other direction */
7837 | while (hfinfo->same_name_prev_id != -1) {
7838 | 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", 7838 , __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", 7838, "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", 7838, "gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo-> same_name_prev_id];;
7839 | }
7840 | }
7841 |
7842 | prev_len = 0; /* Reset handled occurrences */
7843 |
7844 | while (hfinfo) {
7845 | finfos = proto_get_finfo_ptr_array(edt->tree, hfinfo->id);
7846 |
7847 | if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7848 | if (occurrence < 0) {
7849 | hfinfo = hfinfo->same_name_next;
7850 | } else {
7851 | hfinfo = hfinfo_same_name_get_prev(hfinfo);
7852 | }
7853 | continue;
7854 | }
7855 |
7856 | /* Are there enough occurrences of the field? */
7857 | if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7858 | if (occurrence < 0) {
7859 | hfinfo = hfinfo->same_name_next;
7860 | } else {
7861 | hfinfo = hfinfo_same_name_get_prev(hfinfo);
7862 | }
7863 | prev_len += len;
7864 | continue;
7865 | }
7866 |
7867 | /* Calculate single index or set outer boundaries */
7868 | if (occurrence < 0) {
7869 | i = occurrence + len + prev_len;
7870 | last = i;
7871 | } else if (occurrence > 0) {
7872 | i = occurrence - 1 - prev_len;
7873 | last = i;
7874 | } else {
7875 | i = 0;
7876 | last = len - 1;
7877 | }
7878 |
7879 | prev_len += len; /* Count handled occurrences */
7880 |
7881 | while (i <= last) {
7882 | finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7883 |
7884 | filter = proto_construct_match_selected_string(finfo, edt);
7885 | if (filter) {
7886 | /* Only add the same expression once (especially for FT_PROTOCOL).
7887 | * The ptr array doesn't have NULL entries so g_str_equal is fine.
7888 | */
7889 | if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7890 | g_ptr_array_add(filter_array, filter);
7891 | }
7892 | }
7893 | i++;
7894 | }
7895 |
7896 | if (occurrence == 0) {
7897 | /* Fetch next hfinfo with same name (abbrev) */
7898 | hfinfo = hfinfo_same_name_get_prev(hfinfo);
7899 | } else {
7900 | hfinfo = NULL((void*)0);
7901 | }
7902 | }
7903 | }
7904 |
7905 | g_ptr_array_add(filter_array, NULL((void*)0));
7906 |
7907 | /* XXX: Should this be || or && ? */
7908 | char *output = g_strjoinv(" || ", (char **)filter_array->pdata);
7909 |
7910 | g_ptr_array_free(filter_array, true1);
7911 |
7912 | return output;
7913 | }
7914 |
7915 | /* Set text of proto_item after having already been created. */
7916 | void
7917 | proto_item_set_text(proto_item *pi, const char *format, ...)
7918 | {
7919 | field_info *fi = NULL((void*)0);
7920 | va_list ap;
7921 |
7922 | TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data )->visible) && proto_item_is_hidden((pi))) { return ; };
7923 |
7924 | fi = PITEM_FINFO(pi)((pi)->finfo);
7925 | if (fi == NULL((void*)0))
7926 | return;
7927 |
7928 | if (fi->rep) {
7929 | ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep)wmem_free(((pi)->tree_data->pinfo->pool), fi->rep );;
7930 | fi->rep = NULL((void*)0);
7931 | }
7932 |
7933 | va_start(ap, format)__builtin_va_start(ap, format);
7934 | proto_tree_set_representation(pi, format, ap);
7935 | va_end(ap)__builtin_va_end(ap);
7936 | }
7937 |
7938 | /* Append to text of proto_item after having already been created. */
7939 | void
7940 | proto_item_append_text(proto_item *pi, const char *format, ...)
7941 | {
7942 | field_info *fi = NULL((void*)0);
7943 | size_t curlen;
7944 | char *str;
7945 | va_list ap;
7946 |
7947 | TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data )->visible) && proto_item_is_hidden((pi))) { return ; };
7948 |
7949 | fi = PITEM_FINFO(pi)((pi)->finfo);
7950 | if (fi == NULL((void*)0)) {
7951 | return;
7952 | }
7953 |
7954 | if (!proto_item_is_hidden(pi)) {
7955 | /*
7956 | * If we don't already have a representation,
7957 | * generate the default representation.
7958 | */
7959 | if (fi->rep == NULL((void*)0)) {
7960 | 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;;
7961 | proto_item_fill_label(fi, fi->rep->representation, &fi->rep->value_pos);
7962 | /* Check for special case append value to FT_NONE or FT_PROTOCOL */
7963 | if ((fi->hfinfo->type == FT_NONE || fi->hfinfo->type == FT_PROTOCOL) &&
7964 | (strncmp(format, ": ", 2) == 0)) {
7965 | fi->rep->value_pos += 2;
7966 | }
7967 | }
7968 | if (fi->rep) {
7969 | curlen = strlen(fi->rep->representation);
7970 | /* curlen doesn't include the \0 byte.
7971 | * XXX: If curlen + 4 > ITEM_LABEL_LENGTH, we can't tell if
7972 | * the representation has already been truncated (of an up
7973 | * to 4 byte UTF-8 character) or is just at the maximum length
7974 | * unless we search for " [truncated]" (which may not be
7975 | * at the start.)
7976 | * It's safer to do nothing.
7977 | */
7978 | if (ITEM_LABEL_LENGTH240 > (curlen + 4)) {
7979 | va_start(ap, format)__builtin_va_start(ap, format);
7980 | str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7981 | va_end(ap)__builtin_va_end(ap);
7982 | 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" , 7982, __func__, str, -1, __uni_endptr); } } while (0); } } while (0);
7983 | /* Keep fi->rep->value_pos */
7984 | curlen = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, curlen, (const uint8_t*)str, 0);
7985 | if (curlen >= ITEM_LABEL_LENGTH240) {
7986 | /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7987 | size_t name_pos = label_find_name_pos(fi->rep);
7988 | label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7989 | }
7990 | fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7991 | }
7992 | }
7993 | }
7994 | }
7995 |
7996 | /* Prepend to text of proto_item after having already been created. */
7997 | void
7998 | proto_item_prepend_text(proto_item *pi, const char *format, ...)
7999 | {
8000 | field_info *fi = NULL((void*)0);
8001 | size_t pos;
8002 | char representation[ITEM_LABEL_LENGTH240];
8003 | char *str;
8004 | va_list ap;
8005 |
8006 | TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data )->visible) && proto_item_is_hidden((pi))) { return ; };
8007 |
8008 | fi = PITEM_FINFO(pi)((pi)->finfo);
8009 | if (fi == NULL((void*)0)) {
8010 | return;
8011 | }
8012 |
8013 | if (!proto_item_is_hidden(pi)) {
8014 | /*
8015 | * If we don't already have a representation,
8016 | * generate the default representation.
8017 | */
8018 | if (fi->rep == NULL((void*)0)) {
8019 | 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;;
8020 | proto_item_fill_label(fi, representation, &fi->rep->value_pos);
8021 | } else
8022 | (void) g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH240);
8023 |
8024 | va_start(ap, format)__builtin_va_start(ap, format);
8025 | str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
8026 | va_end(ap)__builtin_va_end(ap);
8027 | 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" , 8027, __func__, str, -1, __uni_endptr); } } while (0); } } while (0);
8028 | fi->rep->value_pos += strlen(str);
8029 | pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, (const uint8_t*)str, 0);
8030 | pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, pos, (const uint8_t*)representation, 0);
8031 | /* XXX: As above, if the old representation is close to the label
8032 | * length, it might already be marked as truncated. */
8033 | if (pos >= ITEM_LABEL_LENGTH240 && (strlen(representation) + 4) <= ITEM_LABEL_LENGTH240) {
8034 | /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
8035 | size_t name_pos = label_find_name_pos(fi->rep);
8036 | label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
8037 | }
8038 | fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
8039 | }
8040 | }
8041 |
8042 | static void
8043 | finfo_set_len(field_info *fi, const unsigned length)
8044 | {
8045 | unsigned length_remaining;
8046 |
8047 | length_remaining = G_LIKELY(fi->ds_tvb)(fi->ds_tvb) ? tvb_captured_length_remaining(fi->ds_tvb, fi->start) : 0;
8048 | if (length > length_remaining)
8049 | fi->length = length_remaining;
8050 | else
8051 | fi->length = length;
8052 |
8053 | /* If we have an FT_PROTOCOL we need to set the length of the fvalue tvbuff as well. */
8054 | if (fvalue_type_ftenum(fi->value) == FT_PROTOCOL) {
8055 | fvalue_set_protocol_length(fi->value, fi->length);
8056 | }
8057 |
8058 | /*
8059 | * You cannot just make the "len" field of a GByteArray
8060 | * larger, if there's no data to back that length;
8061 | * you can only make it smaller.
8062 | */
8063 | if (fvalue_type_ftenum(fi->value) == FT_BYTES && fi->length > 0) {
8064 | GBytes *bytes = fvalue_get_bytes(fi->value);
8065 | size_t size;
8066 | const void *data = g_bytes_get_data(bytes, &size);
8067 | if ((size_t)fi->length <= size) {
8068 | fvalue_set_bytes_data(fi->value, data, fi->length);
8069 | }
8070 | g_bytes_unref(bytes);
8071 | }
8072 | }
8073 |
8074 | void
8075 | proto_item_set_len(proto_item *pi, const unsigned length)
8076 | {
8077 | field_info *fi;
8078 |
8079 | if (pi == NULL((void*)0))
8080 | return;
8081 |
8082 | fi = PITEM_FINFO(pi)((pi)->finfo);
8083 | if (fi == NULL((void*)0))
8084 | return;
8085 |
8086 | finfo_set_len(fi, length);
8087 | }
8088 |
8089 | /*
8090 | * Sets the length of the item based on its start and on the specified
8091 | * offset, which is the offset past the end of the item; as the start
8092 | * in the item is relative to the beginning of the data source tvbuff,
8093 | * we need to pass in a tvbuff - the end offset is relative to the beginning
8094 | * of that tvbuff.
8095 | */
8096 | void
8097 | proto_item_set_end(proto_item *pi, tvbuff_t *tvb, unsigned end)
8098 | {
8099 | field_info *fi;
8100 | unsigned length;
8101 |
8102 | if (pi == NULL((void*)0))
8103 | return;
8104 |
8105 | fi = PITEM_FINFO(pi)((pi)->finfo);
8106 | if (fi == NULL((void*)0))
8107 | return;
8108 |
8109 | if (G_LIKELY(tvb)(tvb)) {
8110 | DISSECTOR_ASSERT(tvb_get_ds_tvb(tvb) == fi->ds_tvb)((void) ((tvb_get_ds_tvb(tvb) == fi->ds_tvb) ? (void)0 : ( proto_report_dissector_bug("%s:%u: failed assertion \"%s\"", "epan/proto.c" , 8110, "tvb_get_ds_tvb(tvb) == fi->ds_tvb"))));
8111 | end += tvb_raw_offset(tvb);
8112 | } else {
8113 | DISSECTOR_ASSERT(NULL == fi->ds_tvb)((void) ((((void*)0) == fi->ds_tvb) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8113, "((void*)0) == fi->ds_tvb" ))));
8114 | }
8115 | DISSECTOR_ASSERT(end >= fi->start)((void) ((end >= fi->start) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8115, "end >= fi->start" ))));
8116 | length = end - fi->start;
8117 |
8118 | finfo_set_len(fi, length);
8119 | }
8120 |
8121 | unsigned
8122 | proto_item_get_len(const proto_item *pi)
8123 | {
8124 | /* XXX - The only use case where this is really guaranteed to work is
8125 | * increasing the length of an item (which has no effect if the item
8126 | * is faked, so it doesn't matter that this returns 0 in that case), e.g.
8127 | *
8128 | * proto_item_set_len(pi, proto_item_get_len(pi) + delta);
8129 | *
8130 | * Should there be a macro or function to do that, and possibly this
8131 | * be deprecated? As a bonus, we could handle overflow.
8132 | */
8133 | field_info *fi;
8134 |
8135 | if (!pi)
8136 | return 0;
8137 | fi = PITEM_FINFO(pi)((pi)->finfo);
8138 | if (fi) {
8139 | return fi->length;
8140 | }
8141 | return 0;
8142 | }
8143 |
8144 | void
8145 | proto_item_set_bits_offset_len(proto_item *ti, int bits_offset, int bits_len) {
8146 | if (!ti) {
8147 | return;
8148 | }
8149 | 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);
8150 | 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);
8151 | }
8152 |
8153 | char *
8154 | proto_item_get_display_repr(wmem_allocator_t *scope, proto_item *pi)
8155 | {
8156 | field_info *fi;
8157 |
8158 | if (!pi)
8159 | return wmem_strdup(scope, "");
8160 | fi = PITEM_FINFO(pi)((pi)->finfo);
8161 | if (!fi)
8162 | return wmem_strdup(scope, "");
8163 | DISSECTOR_ASSERT(fi->hfinfo != NULL)((void) ((fi->hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8163, "fi->hfinfo != ((void*)0)" ))));
8164 | return fvalue_to_string_repr(scope, fi->value, FTREPR_DISPLAY, fi->hfinfo->display);
8165 | }
8166 |
8167 | proto_tree *
8168 | proto_tree_create_root(packet_info *pinfo)
8169 | {
8170 | proto_node *pnode;
8171 |
8172 | /* Initialize the proto_node */
8173 | pnode = g_slice_new(proto_tree)((proto_tree*) g_slice_alloc ((sizeof (proto_tree) > 0 ? sizeof (proto_tree) : 1)));
8174 | PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = (( void*)0); pnode->next = ((void*)0);;
8175 | pnode->parent = NULL((void*)0);
8176 | PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0);
8177 | pnode->tree_data = g_slice_new(tree_data_t)((tree_data_t*) g_slice_alloc ((sizeof (tree_data_t) > 0 ? sizeof (tree_data_t) : 1)));
8178 |
8179 | /* Make sure we can access pinfo everywhere */
8180 | pnode->tree_data->pinfo = pinfo;
8181 |
8182 | /* Don't initialize the tree_data_t. Wait until we know we need it */
8183 | pnode->tree_data->interesting_hfids = NULL((void*)0);
8184 |
8185 | /* Set the default to false so it's easier to
8186 | * find errors; if we expect to see the protocol tree
8187 | * but for some reason the default 'visible' is not
8188 | * changed, then we'll find out very quickly. */
8189 | pnode->tree_data->visible = false0;
8190 |
8191 | /* Make sure that we fake protocols (if possible) */
8192 | pnode->tree_data->fake_protocols = true1;
8193 |
8194 | /* Keep track of the number of children */
8195 | pnode->tree_data->count = 0;
8196 |
8197 | /* Initialize our loop checks */
8198 | pnode->tree_data->idle_count_ds_tvb = NULL((void*)0);
8199 | pnode->tree_data->max_start = 0;
8200 | pnode->tree_data->start_idle_count = 0;
8201 |
8202 | return (proto_tree *)pnode;
8203 | }
8204 |
8205 |
8206 | /* "prime" a proto_tree with a single hfid that a dfilter
8207 | * is interested in. */
8208 | void
8209 | proto_tree_prime_with_hfid(proto_tree *tree _U___attribute__((unused)), const int hfid)
8210 | {
8211 | header_field_info *hfinfo;
8212 |
8213 | 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", 8213, __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", 8213, "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", 8213, "gpa_hfinfo.hfi[hfid] != ((void*)0)", "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];;
8214 | /* this field is referenced by a filter so increase the refcount.
8215 | also increase the refcount for the parent, i.e the protocol.
8216 | Don't increase the refcount if we're already printing the
8217 | type, as that is a superset of direct reference.
8218 | */
8219 | if (hfinfo->ref_type != HF_REF_TYPE_PRINT) {
8220 | hfinfo->ref_type = HF_REF_TYPE_DIRECT;
8221 | }
8222 | /* only increase the refcount if there is a parent.
8223 | if this is a protocol and not a field then parent will be -1
8224 | and there is no parent to add any refcounting for.
8225 | */
8226 | if (hfinfo->parent != -1) {
8227 | header_field_info *parent_hfinfo;
8228 | 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", 8228 , __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", 8228, "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", 8228, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!" )))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];;
8229 |
8230 | /* Mark parent as indirectly referenced unless it is already directly
8231 | * referenced, i.e. the user has specified the parent in a filter.
8232 | */
8233 | if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8234 | parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8235 | }
8236 | }
8237 |
8238 | /* "prime" a proto_tree with a single hfid that a dfilter
8239 | * is interested in. */
8240 | void
8241 | proto_tree_prime_with_hfid_print(proto_tree *tree _U___attribute__((unused)), const int hfid)
8242 | {
8243 | header_field_info *hfinfo;
8244 |
8245 | 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", 8245, __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", 8245, "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", 8245, "gpa_hfinfo.hfi[hfid] != ((void*)0)", "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];;
8246 | /* this field is referenced by an (output) filter so increase the refcount.
8247 | also increase the refcount for the parent, i.e the protocol.
8248 | */
8249 | hfinfo->ref_type = HF_REF_TYPE_PRINT;
8250 | /* only increase the refcount if there is a parent.
8251 | if this is a protocol and not a field then parent will be -1
8252 | and there is no parent to add any refcounting for.
8253 | */
8254 | if (hfinfo->parent != -1) {
8255 | header_field_info *parent_hfinfo;
8256 | 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", 8256 , __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", 8256, "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", 8256, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!" )))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];;
8257 |
8258 | /* Mark parent as indirectly referenced unless it is already directly
8259 | * referenced, i.e. the user has specified the parent in a filter.
8260 | */
8261 | if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8262 | parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8263 | }
8264 | }
8265 |
8266 | proto_tree *
8267 | proto_item_add_subtree(proto_item *pi, const int idx) {
8268 | field_info *fi;
8269 |
8270 | if (!pi)
8271 | return NULL((void*)0);
8272 |
8273 | 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", 8273, "idx >= 0 && idx < num_tree_types" ))));
8274 |
8275 | fi = PITEM_FINFO(pi)((pi)->finfo);
8276 | if (!fi)
8277 | return (proto_tree *)pi;
8278 |
8279 | fi->tree_type = idx;
8280 |
8281 | return (proto_tree *)pi;
8282 | }
8283 |
8284 | proto_tree *
8285 | proto_item_get_subtree(proto_item *pi) {
8286 | field_info *fi;
8287 |
8288 | if (!pi)
8289 | return NULL((void*)0);
8290 | fi = PITEM_FINFO(pi)((pi)->finfo);
8291 | if ( (fi) && (fi->tree_type == -1) )
8292 | return NULL((void*)0);
8293 | return (proto_tree *)pi;
8294 | }
8295 |
8296 | proto_item *
8297 | proto_item_get_parent(const proto_item *ti) {
8298 | if (!ti)
8299 | return NULL((void*)0);
8300 | return ti->parent;
8301 | }
8302 |
8303 | proto_item *
8304 | proto_item_get_parent_nth(proto_item *ti, int gen) {
8305 | if (!ti)
8306 | return NULL((void*)0);
8307 | while (gen--) {
8308 | ti = ti->parent;
8309 | if (!ti)
8310 | return NULL((void*)0);
8311 | }
8312 | return ti;
8313 | }
8314 |
8315 |
8316 | proto_item *
8317 | proto_tree_get_parent(proto_tree *tree) {
8318 | if (!tree)
8319 | return NULL((void*)0);
8320 | return (proto_item *)tree;
8321 | }
8322 |
8323 | proto_tree *
8324 | proto_tree_get_parent_tree(proto_tree *tree) {
8325 | if (!tree)
8326 | return NULL((void*)0);
8327 |
8328 | /* we're the root tree, there's no parent
8329 | return ourselves so the caller has at least a tree to attach to */
8330 | if (!tree->parent)
8331 | return tree;
8332 |
8333 | return (proto_tree *)tree->parent;
8334 | }
8335 |
8336 | proto_tree *
8337 | proto_tree_get_root(proto_tree *tree) {
8338 | if (!tree)
8339 | return NULL((void*)0);
8340 | while (tree->parent) {
8341 | tree = tree->parent;
8342 | }
8343 | return tree;
8344 | }
8345 |
8346 | void
8347 | proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
8348 | proto_item *item_to_move)
8349 | {
8350 | /* This function doesn't generate any values. It only reorganizes the protocol tree
8351 | * so we can bail out immediately if it isn't visible. */
8352 | if (!tree || !PTREE_DATA(tree)((tree)->tree_data)->visible)
8353 | return;
8354 |
8355 | 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", 8355, "item_to_move->parent == tree" ))));
8356 | 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", 8356, "fixed_item->parent == tree" ))));
8357 |
8358 | /*** cut item_to_move out ***/
8359 |
8360 | /* is item_to_move the first? */
8361 | if (tree->first_child == item_to_move) {
8362 | /* simply change first child to next */
8363 | tree->first_child = item_to_move->next;
8364 |
8365 | 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", 8365, "tree->last_child != item_to_move" ))));
8366 | } else {
8367 | proto_item *curr_item;
8368 | /* find previous and change it's next */
8369 | for (curr_item = tree->first_child; curr_item != NULL((void*)0); curr_item = curr_item->next) {
8370 | if (curr_item->next == item_to_move) {
8371 | break;
8372 | }
8373 | }
8374 |
8375 | DISSECTOR_ASSERT(curr_item)((void) ((curr_item) ? (void)0 : (proto_report_dissector_bug( "%s:%u: failed assertion \"%s\"", "epan/proto.c", 8375, "curr_item" ))));
8376 |
8377 | curr_item->next = item_to_move->next;
8378 |
8379 | /* fix last_child if required */
8380 | if (tree->last_child == item_to_move) {
8381 | tree->last_child = curr_item;
8382 | }
8383 | }
8384 |
8385 | /*** insert to_move after fixed ***/
8386 | item_to_move->next = fixed_item->next;
8387 | fixed_item->next = item_to_move;
8388 | if (tree->last_child == fixed_item) {
8389 | tree->last_child = item_to_move;
8390 | }
8391 | }
8392 |
8393 | void
8394 | proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, unsigned start,
8395 | const unsigned length)
8396 | {
8397 | field_info *fi;
8398 |
8399 | if (tree == NULL((void*)0))
8400 | return;
8401 |
8402 | fi = PTREE_FINFO(tree)((tree)->finfo);
8403 | if (fi == NULL((void*)0))
8404 | return;
8405 |
8406 | /* We don't store a separate data source tvb for the appendix, so
8407 | * it must be from the same data source. (XXX - Are there any
8408 | * situations where it makes sense to have an appendix from a
8409 | * different data source?) */
8410 | if (G_LIKELY(tvb)(tvb)) {
8411 | DISSECTOR_ASSERT(tvb_get_ds_tvb(tvb) == fi->ds_tvb)((void) ((tvb_get_ds_tvb(tvb) == fi->ds_tvb) ? (void)0 : ( proto_report_dissector_bug("%s:%u: failed assertion \"%s\"", "epan/proto.c" , 8411, "tvb_get_ds_tvb(tvb) == fi->ds_tvb"))));
8412 | start += tvb_raw_offset(tvb);
8413 | } else {
8414 | DISSECTOR_ASSERT(NULL == fi->ds_tvb)((void) ((((void*)0) == fi->ds_tvb) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8414, "((void*)0) == fi->ds_tvb" ))));
8415 | }
8416 |
8417 | /* XXX - DISSECTOR_ASSERT that the appendix doesn't overlap the
8418 | * main body? */
8419 |
8420 | fi->appendix_start = start;
8421 | fi->appendix_length = length;
8422 | }
8423 |
8424 | static void
8425 | check_protocol_filter_name_or_fail(const char *filter_name)
8426 | {
8427 | /* Require at least two characters. */
8428 | if (filter_name[0] == '\0' || filter_name[1] == '\0') {
8429 | 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);
8430 | }
8431 |
8432 | if (proto_check_field_name(filter_name) != '\0') {
8433 | 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)
8434 | " 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)
8435 | " 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);
8436 | }
8437 |
8438 | /* Check that it doesn't match some very common numeric forms. */
8439 | if (filter_name[0] == '0' &&
8440 | (filter_name[1] == 'x' || filter_name[1] == 'X' ||
8441 | filter_name[1] == 'b' || filter_name[1] == 'B')) {
8442 | 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])
8443 | 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]);
8444 | }
8445 |
8446 | /* Names starting with a digit must not contain a minus sign (currently not checked at runtime). */
8447 |
8448 | /* Check that it contains at least one letter. */
8449 | bool_Bool have_letter = false0;
8450 | for (const char *s = filter_name; *s != '\0'; s++) {
8451 | if (g_ascii_isalpha(*s)((g_ascii_table[(guchar) (*s)] & G_ASCII_ALPHA) != 0)) {
8452 | have_letter = true1;
8453 | break;
8454 | }
8455 | }
8456 | if (!have_letter) {
8457 | 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)
8458 | filter_name)proto_report_dissector_bug("Protocol filter name \"%s\" must contain at least one letter a-z." , filter_name);
8459 | }
8460 |
8461 | /* Check for reserved keywords. */
8462 | if (g_hash_table_contains(proto_reserved_filter_names, filter_name)) {
8463 | 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)
8464 | " 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);
8465 | }
8466 | }
8467 |
8468 | int
8469 | proto_register_protocol(const char *name, const char *short_name,
8470 | const char *filter_name)
8471 | {
8472 | protocol_t *protocol;
8473 | header_field_info *hfinfo;
8474 |
8475 | check_protocol_filter_name_or_fail(filter_name);
8476 |
8477 | /*
8478 | * Add this protocol to the list of known protocols;
8479 | * the list is sorted by protocol short name.
8480 | */
8481 | protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8482 | protocol->name = name;
8483 | protocol->short_name = short_name;
8484 | protocol->filter_name = filter_name;
8485 | protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8486 | protocol->is_enabled = true1; /* protocol is enabled by default */
8487 | protocol->enabled_by_default = true1; /* see previous comment */
8488 | protocol->can_toggle = true1;
8489 | protocol->parent_proto_id = -1;
8490 | protocol->heur_list = NULL((void*)0);
8491 |
8492 | /* List will be sorted later by name, when all protocols completed registering */
8493 | protocols = g_list_prepend(protocols, protocol);
8494 | /*
8495 | * Make sure there's not already a protocol with any of those
8496 | * names. Crash if there is, as that's an error in the code
8497 | * or an inappropriate plugin.
8498 | * This situation has to be fixed to not register more than one
8499 | * protocol with the same name.
8500 | */
8501 | if (!g_hash_table_insert(proto_names, (void *)name, protocol)) {
8502 | /* ws_error will terminate the program */
8503 | 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)
8504 | " 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);
8505 | }
8506 | if (!g_hash_table_insert(proto_filter_names, (void *)filter_name, protocol)) {
8507 | 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)
8508 | " 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);
8509 | }
8510 | if (!g_hash_table_insert(proto_short_names, (void *)short_name, protocol)) {
8511 | 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)
8512 | " 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);
8513 | }
8514 |
8515 | /* Here we allocate a new header_field_info struct */
8516 | hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc ((sizeof (header_field_info ) > 0 ? sizeof (header_field_info) : 1)));
8517 | hfinfo->name = name;
8518 | hfinfo->abbrev = filter_name;
8519 | hfinfo->type = FT_PROTOCOL;
8520 | hfinfo->display = BASE_NONE;
8521 | hfinfo->strings = protocol;
8522 | hfinfo->bitmask = 0;
8523 | hfinfo->ref_type = HF_REF_TYPE_NONE;
8524 | hfinfo->blurb = NULL((void*)0);
8525 | hfinfo->parent = -1; /* This field differentiates protos and fields */
8526 |
8527 | protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8528 | return protocol->proto_id;
8529 | }
8530 |
8531 | int
8532 | proto_register_protocol_in_name_only(const char *name, const char *short_name, const char *filter_name, int parent_proto, enum ftenum field_type)
8533 | {
8534 | protocol_t *protocol;
8535 | header_field_info *hfinfo;
8536 |
8537 | /*
8538 | * Helper protocols don't need the strict rules as a "regular" protocol
8539 | * Just register it in a list and make a hf_ field from it
8540 | */
8541 | if ((field_type != FT_PROTOCOL) && (field_type != FT_BYTES)) {
8542 | 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);
8543 | }
8544 |
8545 | if (parent_proto <= 0) {
8546 | 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)
8547 | " 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);
8548 | }
8549 |
8550 | check_protocol_filter_name_or_fail(filter_name);
8551 |
8552 | /* Add this protocol to the list of helper protocols (just so it can be properly freed) */
8553 | protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8554 | protocol->name = name;
8555 | protocol->short_name = short_name;
8556 | protocol->filter_name = filter_name;
8557 | protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8558 |
8559 | /* Enabling and toggling is really determined by parent protocol,
8560 | but provide default values here */
8561 | protocol->is_enabled = true1;
8562 | protocol->enabled_by_default = true1;
8563 | protocol->can_toggle = true1;
8564 |
8565 | protocol->parent_proto_id = parent_proto;
8566 | protocol->heur_list = NULL((void*)0);
8567 |
8568 | /* List will be sorted later by name, when all protocols completed registering */
8569 | protocols = g_list_prepend(protocols, protocol);
8570 |
8571 | /* Here we allocate a new header_field_info struct */
8572 | hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc ((sizeof (header_field_info ) > 0 ? sizeof (header_field_info) : 1)));
8573 | hfinfo->name = name;
8574 | hfinfo->abbrev = filter_name;
8575 | hfinfo->type = field_type;
8576 | hfinfo->display = BASE_NONE;
8577 | if (field_type == FT_BYTES) {
8578 | hfinfo->display |= (BASE_NO_DISPLAY_VALUE0x00002000|BASE_PROTOCOL_INFO0x00004000);
8579 | }
8580 | hfinfo->strings = protocol;
8581 | hfinfo->bitmask = 0;
8582 | hfinfo->ref_type = HF_REF_TYPE_NONE;
8583 | hfinfo->blurb = NULL((void*)0);
8584 | hfinfo->parent = -1; /* This field differentiates protos and fields */
8585 |
8586 | protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8587 | return protocol->proto_id;
8588 | }
8589 |
8590 | bool_Bool
8591 | proto_deregister_protocol(const char *short_name)
8592 | {
8593 | protocol_t *protocol;
8594 | header_field_info *hfinfo;
8595 | int proto_id;
8596 | unsigned i;
8597 |
8598 | proto_id = proto_get_id_by_short_name(short_name);
8599 | protocol = find_protocol_by_id(proto_id);
8600 | if (protocol == NULL((void*)0))
8601 | return false0;
8602 |
8603 | g_hash_table_remove(proto_names, protocol->name);
8604 | g_hash_table_remove(proto_short_names, (void *)short_name);
8605 | g_hash_table_remove(proto_filter_names, (void *)protocol->filter_name);
8606 |
8607 | if (protocol->fields) {
8608 | for (i = 0; i < protocol->fields->len; i++) {
8609 | hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8610 | hfinfo_remove_from_gpa_name_map(hfinfo);
8611 | expert_deregister_expertinfo(hfinfo->abbrev);
8612 | g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
8613 | }
8614 | g_ptr_array_free(protocol->fields, true1);
8615 | protocol->fields = NULL((void*)0);
8616 | }
8617 |
8618 | g_list_free(protocol->heur_list);
8619 |
8620 | /* Remove this protocol from the list of known protocols */
8621 | protocols = g_list_remove(protocols, protocol);
8622 |
8623 | g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
8624 | wmem_map_remove(gpa_name_map, protocol->filter_name);
8625 |
8626 | g_free(last_field_name)(__builtin_object_size ((last_field_name), 0) != ((size_t) - 1 )) ? g_free_sized (last_field_name, __builtin_object_size ((last_field_name ), 0)) : (g_free) (last_field_name);
8627 | last_field_name = NULL((void*)0);
8628 |
8629 | return true1;
8630 | }
8631 |
8632 | void
8633 | proto_register_alias(const int proto_id, const char *alias_name)
8634 | {
8635 | protocol_t *protocol;
8636 |
8637 | protocol = find_protocol_by_id(proto_id);
8638 | if (alias_name && protocol) {
8639 | g_hash_table_insert(gpa_protocol_aliases, (void *) alias_name, (void *)protocol->filter_name);
8640 | }
8641 | }
8642 |
8643 | /*
8644 | * Routines to use to iterate over the protocols.
8645 | * The argument passed to the iterator routines is an opaque cookie to
8646 | * their callers; it's the GList pointer for the current element in
8647 | * the list.
8648 | * The ID of the protocol is returned, or -1 if there is no protocol.
8649 | */
8650 | int
8651 | proto_get_first_protocol(void **cookie)
8652 | {
8653 | protocol_t *protocol;
8654 |
8655 | if (protocols == NULL((void*)0))
8656 | return -1;
8657 | *cookie = protocols;
8658 | protocol = (protocol_t *)protocols->data;
8659 | return protocol->proto_id;
8660 | }
8661 |
8662 | int
8663 | proto_get_data_protocol(void *cookie)
8664 | {
8665 | GList *list_item = (GList *)cookie;
8666 |
8667 | protocol_t *protocol = (protocol_t *)list_item->data;
8668 | return protocol->proto_id;
8669 | }
8670 |
8671 | int
8672 | proto_get_next_protocol(void **cookie)
8673 | {
8674 | GList *list_item = (GList *)*cookie;
8675 | protocol_t *protocol;
8676 |
8677 | list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0) );
8678 | if (list_item == NULL((void*)0))
8679 | return -1;
8680 | *cookie = list_item;
8681 | protocol = (protocol_t *)list_item->data;
8682 | return protocol->proto_id;
8683 | }
8684 |
8685 | header_field_info *
8686 | proto_get_first_protocol_field(const int proto_id, void **cookie)
8687 | {
8688 | protocol_t *protocol = find_protocol_by_id(proto_id);
8689 |
8690 | if ((protocol == NULL((void*)0)) || (protocol->fields == NULL((void*)0)) || (protocol->fields->len == 0))
8691 | return NULL((void*)0);
8692 |
8693 | *cookie = GUINT_TO_POINTER(0)((gpointer) (gulong) (0));
8694 | return (header_field_info *)g_ptr_array_index(protocol->fields, 0)((protocol->fields)->pdata)[0];
8695 | }
8696 |
8697 | header_field_info *
8698 | proto_get_next_protocol_field(const int proto_id, void **cookie)
8699 | {
8700 | protocol_t *protocol = find_protocol_by_id(proto_id);
8701 | unsigned i = GPOINTER_TO_UINT(*cookie)((guint) (gulong) (*cookie));
8702 |
8703 | i++;
8704 |
8705 | if ((protocol->fields == NULL((void*)0)) || (i >= protocol->fields->len))
8706 | return NULL((void*)0);
8707 |
8708 | *cookie = GUINT_TO_POINTER(i)((gpointer) (gulong) (i));
8709 | return (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8710 | }
8711 |
8712 | protocol_t *
8713 | find_protocol_by_id(const int proto_id)
8714 | {
8715 | header_field_info *hfinfo;
8716 |
8717 | if (proto_id <= 0)
8718 | return NULL((void*)0);
8719 |
8720 | 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", 8720, __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", 8720, "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", 8720, "gpa_hfinfo.hfi[proto_id] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];;
8721 | if (hfinfo->type != FT_PROTOCOL) {
8722 | 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", 8722, "hfinfo->display & 0x00004000" ))));
8723 | }
8724 | return (protocol_t *)hfinfo->strings;
8725 | }
8726 |
8727 | int
8728 | proto_get_id(const protocol_t *protocol)
8729 | {
8730 | return protocol->proto_id;
8731 | }
8732 |
8733 | bool_Bool
8734 | proto_name_already_registered(const char *name)
8735 | {
8736 | DISSECTOR_ASSERT_HINT(name, "No name present")((void) ((name) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 8736, "name", "No name present"))));
8737 |
8738 | if (g_hash_table_lookup(proto_names, name) != NULL((void*)0))
8739 | return true1;
8740 | return false0;
8741 | }
8742 |
8743 | int
8744 | proto_get_id_by_filter_name(const char *filter_name)
8745 | {
8746 | const protocol_t *protocol = NULL((void*)0);
8747 |
8748 | 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", 8748, "filter_name", "No filter name present"))));
8749 |
8750 | protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
8751 |
8752 | if (protocol == NULL((void*)0))
8753 | return -1;
8754 | return protocol->proto_id;
8755 | }
8756 |
8757 | int
8758 | proto_get_id_by_short_name(const char *short_name)
8759 | {
8760 | const protocol_t *protocol = NULL((void*)0);
8761 |
8762 | 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", 8762, "short_name", "No short name present"))));
8763 |
8764 | protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
8765 |
8766 | if (protocol == NULL((void*)0))
8767 | return -1;
8768 | return protocol->proto_id;
8769 | }
8770 |
8771 | const char *
8772 | proto_get_protocol_name(const int proto_id)
8773 | {
8774 | protocol_t *protocol;
8775 |
8776 | protocol = find_protocol_by_id(proto_id);
8777 |
8778 | if (protocol == NULL((void*)0))
8779 | return NULL((void*)0);
8780 | return protocol->name;
8781 | }
8782 |
8783 | const char *
8784 | proto_get_protocol_short_name(const protocol_t *protocol)
8785 | {
8786 | if (protocol == NULL((void*)0))
8787 | return "(none)";
8788 | return protocol->short_name;
8789 | }
8790 |
8791 | const char *
8792 | proto_get_protocol_long_name(const protocol_t *protocol)
8793 | {
8794 | if (protocol == NULL((void*)0))
8795 | return "(none)";
8796 | return protocol->name;
8797 | }
8798 |
8799 | const char *
8800 | proto_get_protocol_filter_name(const int proto_id)
8801 | {
8802 | protocol_t *protocol;
8803 |
8804 | protocol = find_protocol_by_id(proto_id);
8805 | if (protocol == NULL((void*)0))
8806 | return "(none)";
8807 | return protocol->filter_name;
8808 | }
8809 |
8810 | void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
8811 | {
8812 | heur_dtbl_entry_t* heuristic_dissector;
8813 |
8814 | if (protocol == NULL((void*)0))
8815 | return;
8816 |
8817 | heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
8818 | if (heuristic_dissector != NULL((void*)0))
8819 | {
8820 | protocol->heur_list = g_list_prepend (protocol->heur_list, heuristic_dissector);
8821 | }
8822 | }
8823 |
8824 | void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, void *user_data)
8825 | {
8826 | if (protocol == NULL((void*)0))
8827 | return;
8828 |
8829 | g_list_foreach(protocol->heur_list, func, user_data);
8830 | }
8831 |
8832 | void
8833 | proto_get_frame_protocols(const wmem_list_t *layers, bool_Bool *is_ip,
8834 | bool_Bool *is_tcp, bool_Bool *is_udp,
8835 | bool_Bool *is_sctp, bool_Bool *is_tls,
8836 | bool_Bool *is_rtp,
8837 | bool_Bool *is_lte_rlc)
8838 | {
8839 | wmem_list_frame_t *protos = wmem_list_head(layers);
8840 | int proto_id;
8841 | const char *proto_name;
8842 |
8843 | /* Walk the list of a available protocols in the packet and
8844 | attempt to find "major" ones. */
8845 | /* It might make more sense to assemble and return a bitfield. */
8846 | while (protos != NULL((void*)0))
8847 | {
8848 | proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8849 | proto_name = proto_get_protocol_filter_name(proto_id);
8850 |
8851 | if (is_ip && ((!strcmp(proto_name, "ip")) ||
8852 | (!strcmp(proto_name, "ipv6")))) {
8853 | *is_ip = true1;
8854 | } else if (is_tcp && !strcmp(proto_name, "tcp")) {
8855 | *is_tcp = true1;
8856 | } else if (is_udp && !strcmp(proto_name, "udp")) {
8857 | *is_udp = true1;
8858 | } else if (is_sctp && !strcmp(proto_name, "sctp")) {
8859 | *is_sctp = true1;
8860 | } else if (is_tls && !strcmp(proto_name, "tls")) {
8861 | *is_tls = true1;
8862 | } else if (is_rtp && !strcmp(proto_name, "rtp")) {
8863 | *is_rtp = true1;
8864 | } else if (is_lte_rlc && (!strcmp(proto_name, "rlc-lte") || !strcmp(proto_name, "rlc-nr"))) {
8865 | *is_lte_rlc = true1;
8866 | }
8867 |
8868 | protos = wmem_list_frame_next(protos);
8869 | }
8870 | }
8871 |
8872 | bool_Bool
8873 | proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
8874 | {
8875 | wmem_list_frame_t *protos = wmem_list_head(layers);
8876 | int proto_id;
8877 | const char *name;
8878 |
8879 | /* Walk the list of a available protocols in the packet and
8880 | attempt to find the specified protocol. */
8881 | while (protos != NULL((void*)0))
8882 | {
8883 | proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8884 | name = proto_get_protocol_filter_name(proto_id);
8885 |
8886 | if (!strcmp(name, proto_name))
8887 | {
8888 | return true1;
8889 | }
8890 |
8891 | protos = wmem_list_frame_next(protos);
8892 | }
8893 |
8894 | return false0;
8895 | }
8896 |
8897 | char *
8898 | proto_list_layers(const packet_info *pinfo)
8899 | {
8900 | wmem_strbuf_t *buf;
8901 | wmem_list_frame_t *layers = wmem_list_head(pinfo->layers);
8902 |
8903 | buf = wmem_strbuf_new_sized(pinfo->pool, 128);
8904 |
8905 | /* Walk the list of layers in the packet and
8906 | return a string of all entries. */
8907 | while (layers != NULL((void*)0))
8908 | {
8909 | wmem_strbuf_append(buf, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(layers))((guint) (gulong) (wmem_list_frame_data(layers)))));
8910 |
8911 | layers = wmem_list_frame_next(layers);
8912 | if (layers != NULL((void*)0)) {
8913 | wmem_strbuf_append_c(buf, ':');
8914 | }
8915 | }
8916 |
8917 | return wmem_strbuf_finalize(buf);
8918 | }
8919 |
8920 | uint8_t
8921 | proto_get_layer_num(const packet_info *pinfo, const int proto_id)
8922 | {
8923 | int *proto_layer_num_ptr;
8924 |
8925 | proto_layer_num_ptr = wmem_map_lookup(pinfo->proto_layers, GINT_TO_POINTER(proto_id)((gpointer) (glong) (proto_id)));
8926 | if (proto_layer_num_ptr == NULL((void*)0)) {
8927 | return 0;
8928 | }
8929 |
8930 | return (uint8_t)*proto_layer_num_ptr;
8931 | }
8932 |
8933 | bool_Bool
8934 | proto_is_pino(const protocol_t *protocol)
8935 | {
8936 | return (protocol->parent_proto_id != -1);
8937 | }
8938 |
8939 | bool_Bool
8940 | // NOLINTNEXTLINE(misc-no-recursion)
8941 | proto_is_protocol_enabled(const protocol_t *protocol)
8942 | {
8943 | if (protocol == NULL((void*)0))
8944 | return false0;
8945 |
8946 | //parent protocol determines enable/disable for helper dissectors
8947 | if (proto_is_pino(protocol))
8948 | return proto_is_protocol_enabled(find_protocol_by_id(protocol->parent_proto_id));
8949 |
8950 | return protocol->is_enabled;
8951 | }
8952 |
8953 | bool_Bool
8954 | // NOLINTNEXTLINE(misc-no-recursion)
8955 | proto_is_protocol_enabled_by_default(const protocol_t *protocol)
8956 | {
8957 | //parent protocol determines enable/disable for helper dissectors
8958 | if (proto_is_pino(protocol))
8959 | return proto_is_protocol_enabled_by_default(find_protocol_by_id(protocol->parent_proto_id));
8960 |
8961 | return protocol->enabled_by_default;
8962 | }
8963 |
8964 | bool_Bool
8965 | // NOLINTNEXTLINE(misc-no-recursion)
8966 | proto_can_toggle_protocol(const int proto_id)
8967 | {
8968 | protocol_t *protocol;
8969 |
8970 | protocol = find_protocol_by_id(proto_id);
8971 | //parent protocol determines toggling for helper dissectors
8972 | if (proto_is_pino(protocol))
8973 | return proto_can_toggle_protocol(protocol->parent_proto_id);
8974 |
8975 | return protocol->can_toggle;
8976 | }
8977 |
8978 | void
8979 | proto_disable_by_default(const int proto_id)
8980 | {
8981 | protocol_t *protocol;
8982 |
8983 | protocol = find_protocol_by_id(proto_id);
8984 | DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8984, "protocol->can_toggle" ))));
8985 | 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", 8985, "proto_is_pino(protocol) == 0" ))));
8986 | protocol->is_enabled = false0;
8987 | protocol->enabled_by_default = false0;
8988 | }
8989 |
8990 | void
8991 | proto_set_decoding(const int proto_id, const bool_Bool enabled)
8992 | {
8993 | protocol_t *protocol;
8994 |
8995 | protocol = find_protocol_by_id(proto_id);
8996 | DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8996, "protocol->can_toggle" ))));
8997 | 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", 8997, "proto_is_pino(protocol) == 0" ))));
8998 | protocol->is_enabled = enabled;
8999 | }
9000 |
9001 | void
9002 | proto_disable_all(void)
9003 | {
9004 | /* This doesn't explicitly disable heuristic protocols,
9005 | * but the heuristic doesn't get called if the parent
9006 | * protocol isn't enabled.
9007 | */
9008 | protocol_t *protocol;
9009 | GList *list_item = protocols;
9010 |
9011 | if (protocols == NULL((void*)0))
9012 | return;
9013 |
9014 | while (list_item) {
9015 | protocol = (protocol_t *)list_item->data;
9016 | if (protocol->can_toggle) {
9017 | protocol->is_enabled = false0;
9018 | }
9019 | list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0) );
9020 | }
9021 | }
9022 |
9023 | static void
9024 | heur_reenable_cb(void *data, void *user_data _U___attribute__((unused)))
9025 | {
9026 | heur_dtbl_entry_t *heur = (heur_dtbl_entry_t*)data;
9027 |
9028 | heur->enabled = heur->enabled_by_default;
9029 | }
9030 |
9031 | void
9032 | proto_reenable_all(void)
9033 | {
9034 | protocol_t *protocol;
9035 | GList *list_item = protocols;
9036 |
9037 | if (protocols == NULL((void*)0))
9038 | return;
9039 |
9040 | while (list_item) {
9041 | protocol = (protocol_t *)list_item->data;
9042 | if (protocol->can_toggle)
9043 | protocol->is_enabled = protocol->enabled_by_default;
9044 | proto_heuristic_dissector_foreach(protocol, heur_reenable_cb, NULL((void*)0));
9045 | list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0) );
9046 | }
9047 | }
9048 |
9049 | void
9050 | proto_set_cant_toggle(const int proto_id)
9051 | {
9052 | protocol_t *protocol;
9053 |
9054 | protocol = find_protocol_by_id(proto_id);
9055 | protocol->can_toggle = false0;
9056 | }
9057 |
9058 | static int
9059 | proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
9060 | {
9061 | g_ptr_array_add(proto->fields, hfi);
9062 |
9063 | return proto_register_field_init(hfi, parent);
9064 | }
9065 |
9066 | /* for use with static arrays only, since we don't allocate our own copies
9067 | of the header_field_info struct contained within the hf_register_info struct */
9068 | void
9069 | proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
9070 | {
9071 | hf_register_info *ptr = hf;
9072 | protocol_t *proto;
9073 | int i;
9074 |
9075 | proto = find_protocol_by_id(parent);
9076 |
9077 | /* if (proto == NULL) - error or return? */
9078 |
9079 | if (proto->fields == NULL((void*)0)) {
9080 | /* Ironically, the NEW_PROTO_TREE_API was removed shortly before
9081 | * GLib introduced g_ptr_array_new_from_array, which might have
9082 | * given a reason to actually use it. (#17774)
9083 | */
9084 | proto->fields = g_ptr_array_sized_new(num_records);
9085 | }
9086 |
9087 | for (i = 0; i < num_records; i++, ptr++) {
9088 | /*
9089 | * Make sure we haven't registered this yet.
9090 | * Most fields have variables associated with them that
9091 | * are initialized to 0; some are initialized to -1 (which
9092 | * was the standard before 4.4).
9093 | *
9094 | * XXX - Since this is called almost 300000 times at startup,
9095 | * it might be nice to compare to only 0 and require
9096 | * dissectors to pass in zero for unregistered fields.
9097 | */
9098 | if (*ptr->p_id != -1 && *ptr->p_id != 0) {
9099 | REPORT_DISSECTOR_BUG(proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered" , ptr->hfinfo.abbrev)
9100 | "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)
9101 | ptr->hfinfo.abbrev)proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered" , ptr->hfinfo.abbrev);
9102 | return;
9103 | }
9104 |
9105 | *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
9106 | }
9107 | }
9108 |
9109 | /* deregister already registered fields */
9110 | void
9111 | proto_deregister_field (const int parent, int hf_id)
9112 | {
9113 | header_field_info *hfi;
9114 | protocol_t *proto;
9115 | unsigned i;
9116 |
9117 | g_free(last_field_name)(__builtin_object_size ((last_field_name), 0) != ((size_t) - 1 )) ? g_free_sized (last_field_name, __builtin_object_size ((last_field_name ), 0)) : (g_free) (last_field_name);
9118 | last_field_name = NULL((void*)0);
9119 |
9120 | if (hf_id == -1 || hf_id == 0)
9121 | return;
9122 |
9123 | proto = find_protocol_by_id (parent);
9124 | if (!proto || proto->fields == NULL((void*)0)) {
9125 | return;
9126 | }
9127 |
9128 | for (i = 0; i < proto->fields->len; i++) {
9129 | hfi = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9130 | if (hfi->id == hf_id) {
9131 | /* Found the hf_id in this protocol */
9132 | wmem_map_remove(gpa_name_map, hfi->abbrev);
9133 | g_ptr_array_remove_index_fast(proto->fields, i);
9134 | g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
9135 | return;
9136 | }
9137 | }
9138 | }
9139 |
9140 | /* Deregister all registered fields starting with a prefix. Use for dynamic registered fields only! */
9141 | void
9142 | proto_deregister_all_fields_with_prefix(const int parent, const char *prefix)
9143 | {
9144 | header_field_info *hfinfo;
9145 | protocol_t *proto;
9146 |
9147 | g_free(last_field_name)(__builtin_object_size ((last_field_name), 0) != ((size_t) - 1 )) ? g_free_sized (last_field_name, __builtin_object_size ((last_field_name ), 0)) : (g_free) (last_field_name);
9148 | last_field_name = NULL((void*)0);
9149 |
9150 | proto = find_protocol_by_id(parent);
9151 | if (proto && proto->fields && proto->fields->len > 0) {
9152 | unsigned i = proto->fields->len;
9153 | do {
9154 | i--;
9155 |
9156 | hfinfo = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9157 | 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) )) {
9158 | hfinfo_remove_from_gpa_name_map(hfinfo);
9159 | expert_deregister_expertinfo(hfinfo->abbrev);
9160 | g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
9161 | g_ptr_array_remove_index_fast(proto->fields, i);
9162 | }
9163 | } while (i > 0);
9164 | }
9165 | }
9166 |
9167 | void
9168 | proto_add_deregistered_data (void *data)
9169 | {
9170 | g_ptr_array_add(deregistered_data, data);
9171 | }
9172 |
9173 | void
9174 | proto_add_deregistered_slice (size_t block_size, void *mem_block)
9175 | {
9176 | struct g_slice_data *slice_data = g_slice_new(struct g_slice_data)((struct g_slice_data*) g_slice_alloc ((sizeof (struct g_slice_data ) > 0 ? sizeof (struct g_slice_data) : 1)));
9177 |
9178 | slice_data->block_size = block_size;
9179 | slice_data->mem_block = mem_block;
9180 |
9181 | g_ptr_array_add(deregistered_slice, slice_data);
9182 | }
9183 |
9184 | void proto_free_field_strings (ftenum_t field_type, unsigned int field_display, const void *field_strings)
9185 | {
9186 | if (field_strings == NULL((void*)0)) {
9187 | return;
9188 | }
9189 |
9190 | switch (field_type) {
9191 | case FT_FRAMENUM:
9192 | /* This is just an integer represented as a pointer */
9193 | break;
9194 | case FT_PROTOCOL: {
9195 | protocol_t *protocol = (protocol_t *)field_strings;
9196 | g_free((char *)protocol->short_name)(__builtin_object_size (((char *)protocol->short_name), 0) != ((size_t) - 1)) ? g_free_sized ((char *)protocol->short_name , __builtin_object_size (((char *)protocol->short_name), 0 )) : (g_free) ((char *)protocol->short_name);
9197 | break;
9198 | }
9199 | case FT_BOOLEAN: {
9200 | true_false_string *tf = (true_false_string *)field_strings;
9201 | g_free((char *)tf->true_string)(__builtin_object_size (((char *)tf->true_string), 0) != ( (size_t) - 1)) ? g_free_sized ((char *)tf->true_string, __builtin_object_size (((char *)tf->true_string), 0)) : (g_free) ((char *)tf-> true_string);
9202 | g_free((char *)tf->false_string)(__builtin_object_size (((char *)tf->false_string), 0) != ( (size_t) - 1)) ? g_free_sized ((char *)tf->false_string, __builtin_object_size (((char *)tf->false_string), 0)) : (g_free) ((char *)tf-> false_string);
9203 | break;
9204 | }
9205 | case FT_UINT40:
9206 | case FT_INT40:
9207 | case FT_UINT48:
9208 | case FT_INT48:
9209 | case FT_UINT56:
9210 | case FT_INT56:
9211 | case FT_UINT64:
9212 | case FT_INT64: {
9213 | if (field_display & BASE_UNIT_STRING0x00001000) {
9214 | unit_name_string *unit = (unit_name_string *)field_strings;
9215 | g_free((char *)unit->singular)(__builtin_object_size (((char *)unit->singular), 0) != (( size_t) - 1)) ? g_free_sized ((char *)unit->singular, __builtin_object_size (((char *)unit->singular), 0)) : (g_free) ((char *)unit-> singular);
9216 | g_free((char *)unit->plural)(__builtin_object_size (((char *)unit->plural), 0) != ((size_t ) - 1)) ? g_free_sized ((char *)unit->plural, __builtin_object_size (((char *)unit->plural), 0)) : (g_free) ((char *)unit-> plural);
9217 | } else if (field_display & BASE_RANGE_STRING0x00000100) {
9218 | range_string *rs = (range_string *)field_strings;
9219 | while (rs->strptr) {
9220 | g_free((char *)rs->strptr)(__builtin_object_size (((char *)rs->strptr), 0) != ((size_t ) - 1)) ? g_free_sized ((char *)rs->strptr, __builtin_object_size (((char *)rs->strptr), 0)) : (g_free) ((char *)rs->strptr );
9221 | rs++;
9222 | }
9223 | } else if (field_display & BASE_EXT_STRING0x00000200) {
9224 | val64_string_ext *vse = (val64_string_ext *)field_strings;
9225 | val64_string *vs = (val64_string *)vse->_vs_p;
9226 | while (vs->strptr) {
9227 | g_free((char *)vs->strptr)(__builtin_object_size (((char *)vs->strptr), 0) != ((size_t ) - 1)) ? g_free_sized ((char *)vs->strptr, __builtin_object_size (((char *)vs->strptr), 0)) : (g_free) ((char *)vs->strptr );
9228 | vs++;
9229 | }
9230 | val64_string_ext_free(vse);
9231 | field_strings = NULL((void*)0);
9232 | } else if (field_display == BASE_CUSTOM) {
9233 | /* this will be a pointer to a function, don't free that */
9234 | field_strings = NULL((void*)0);
9235 | } else {
9236 | val64_string *vs64 = (val64_string *)field_strings;
9237 | while (vs64->strptr) {
9238 | g_free((char *)vs64->strptr)(__builtin_object_size (((char *)vs64->strptr), 0) != ((size_t ) - 1)) ? g_free_sized ((char *)vs64->strptr, __builtin_object_size (((char *)vs64->strptr), 0)) : (g_free) ((char *)vs64-> strptr);
9239 | vs64++;
9240 | }
9241 | }
9242 | break;
9243 | }
9244 | case FT_CHAR:
9245 | case FT_UINT8:
9246 | case FT_INT8:
9247 | case FT_UINT16:
9248 | case FT_INT16:
9249 | case FT_UINT24:
9250 | case FT_INT24:
9251 | case FT_UINT32:
9252 | case FT_INT32:
9253 | case FT_FLOAT:
9254 | case FT_DOUBLE: {
9255 | if (field_display & BASE_UNIT_STRING0x00001000) {
9256 | unit_name_string *unit = (unit_name_string *)field_strings;
9257 | g_free((char *)unit->singular)(__builtin_object_size (((char *)unit->singular), 0) != (( size_t) - 1)) ? g_free_sized ((char *)unit->singular, __builtin_object_size (((char *)unit->singular), 0)) : (g_free) ((char *)unit-> singular);
9258 | g_free((char *)unit->plural)(__builtin_object_size (((char *)unit->plural), 0) != ((size_t ) - 1)) ? g_free_sized ((char *)unit->plural, __builtin_object_size (((char *)unit->plural), 0)) : (g_free) ((char *)unit-> plural);
9259 | } else if (field_display & BASE_RANGE_STRING0x00000100) {
9260 | range_string *rs = (range_string *)field_strings;
9261 | while (rs->strptr) {
9262 | g_free((char *)rs->strptr)(__builtin_object_size (((char *)rs->strptr), 0) != ((size_t ) - 1)) ? g_free_sized ((char *)rs->strptr, __builtin_object_size (((char *)rs->strptr), 0)) : (g_free) ((char *)rs->strptr );
9263 | rs++;
9264 | }
9265 | } else if (field_display & BASE_EXT_STRING0x00000200) {
9266 | value_string_ext *vse = (value_string_ext *)field_strings;
9267 | value_string *vs = (value_string *)vse->_vs_p;
9268 | while (vs->strptr) {
9269 | g_free((char *)vs->strptr)(__builtin_object_size (((char *)vs->strptr), 0) != ((size_t ) - 1)) ? g_free_sized ((char *)vs->strptr, __builtin_object_size (((char *)vs->strptr), 0)) : (g_free) ((char *)vs->strptr );
9270 | vs++;
9271 | }
9272 | value_string_ext_free(vse);
9273 | field_strings = NULL((void*)0);
9274 | } else if (field_display == BASE_CUSTOM) {
9275 | /* this will be a pointer to a function, don't free that */
9276 | field_strings = NULL((void*)0);
9277 | } else {
9278 | value_string *vs = (value_string *)field_strings;
9279 | while (vs->strptr) {
9280 | g_free((char *)vs->strptr)(__builtin_object_size (((char *)vs->strptr), 0) != ((size_t ) - 1)) ? g_free_sized ((char *)vs->strptr, __builtin_object_size (((char *)vs->strptr), 0)) : (g_free) ((char *)vs->strptr );
9281 | vs++;
9282 | }
9283 | }
9284 | break;
9285 | default:
9286 | break;
9287 | }
9288 | }
9289 |
9290 | if (field_type != FT_FRAMENUM) {
9291 | g_free((void *)field_strings)(__builtin_object_size (((void *)field_strings), 0) != ((size_t ) - 1)) ? g_free_sized ((void *)field_strings, __builtin_object_size (((void *)field_strings), 0)) : (g_free) ((void *)field_strings );
9292 | }
9293 | }
9294 |
9295 | static void
9296 | free_deregistered_field (void *data, void *user_data _U___attribute__((unused)))
9297 | {
9298 | header_field_info *hfi = (header_field_info *) data;
9299 | int hf_id = hfi->id;
9300 |
9301 | g_free((char *)hfi->name)(__builtin_object_size (((char *)hfi->name), 0) != ((size_t ) - 1)) ? g_free_sized ((char *)hfi->name, __builtin_object_size (((char *)hfi->name), 0)) : (g_free) ((char *)hfi->name );
9302 | g_free((char *)hfi->abbrev)(__builtin_object_size (((char *)hfi->abbrev), 0) != ((size_t ) - 1)) ? g_free_sized ((char *)hfi->abbrev, __builtin_object_size (((char *)hfi->abbrev), 0)) : (g_free) ((char *)hfi->abbrev );
9303 | g_free((char *)hfi->blurb)(__builtin_object_size (((char *)hfi->blurb), 0) != ((size_t ) - 1)) ? g_free_sized ((char *)hfi->blurb, __builtin_object_size (((char *)hfi->blurb), 0)) : (g_free) ((char *)hfi->blurb );
9304 |
9305 | proto_free_field_strings(hfi->type, hfi->display, hfi->strings);
9306 |
9307 | if (hfi->parent == -1)
9308 | 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);
9309 |
9310 | gpa_hfinfo.hfi[hf_id] = NULL((void*)0); /* Invalidate this hf_id / proto_id */
9311 | }
9312 |
9313 | static void
9314 | free_deregistered_data (void *data, void *user_data _U___attribute__((unused)))
9315 | {
9316 | g_free (data)(__builtin_object_size ((data), 0) != ((size_t) - 1)) ? g_free_sized (data, __builtin_object_size ((data), 0)) : (g_free) (data);
9317 | }
9318 |
9319 | static void
9320 | free_deregistered_slice (void *data, void *user_data _U___attribute__((unused)))
9321 | {
9322 | struct g_slice_data *slice_data = (struct g_slice_data *)data;
9323 |
9324 | g_slice_free1(slice_data->block_size, slice_data->mem_block);
9325 | 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);
9326 | }
9327 |
9328 | /* free deregistered fields and data */
9329 | void
9330 | proto_free_deregistered_fields (void)
9331 | {
9332 | expert_free_deregistered_expertinfos();
9333 |
9334 | g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL((void*)0));
9335 | g_ptr_array_free(deregistered_fields, true1);
9336 | deregistered_fields = g_ptr_array_new();
9337 |
9338 | g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL((void*)0));
9339 | g_ptr_array_free(deregistered_data, true1);
9340 | deregistered_data = g_ptr_array_new();
9341 |
9342 | g_ptr_array_foreach(deregistered_slice, free_deregistered_slice, NULL((void*)0));
9343 | g_ptr_array_free(deregistered_slice, true1);
9344 | deregistered_slice = g_ptr_array_new();
9345 | }
9346 |
9347 | static const value_string hf_display[] = {
9348 | { BASE_NONE, "BASE_NONE" },
9349 | { BASE_DEC, "BASE_DEC" },
9350 | { BASE_HEX, "BASE_HEX" },
9351 | { BASE_OCT, "BASE_OCT" },
9352 | { BASE_DEC_HEX, "BASE_DEC_HEX" },
9353 | { BASE_HEX_DEC, "BASE_HEX_DEC" },
9354 | { BASE_CUSTOM, "BASE_CUSTOM" },
9355 | { BASE_NONE|BASE_RANGE_STRING0x00000100, "BASE_NONE|BASE_RANGE_STRING" },
9356 | { BASE_DEC|BASE_RANGE_STRING0x00000100, "BASE_DEC|BASE_RANGE_STRING" },
9357 | { BASE_HEX|BASE_RANGE_STRING0x00000100, "BASE_HEX|BASE_RANGE_STRING" },
9358 | { BASE_OCT|BASE_RANGE_STRING0x00000100, "BASE_OCT|BASE_RANGE_STRING" },
9359 | { BASE_DEC_HEX|BASE_RANGE_STRING0x00000100, "BASE_DEC_HEX|BASE_RANGE_STRING" },
9360 | { BASE_HEX_DEC|BASE_RANGE_STRING0x00000100, "BASE_HEX_DEC|BASE_RANGE_STRING" },
9361 | { BASE_CUSTOM|BASE_RANGE_STRING0x00000100, "BASE_CUSTOM|BASE_RANGE_STRING" },
9362 | { BASE_NONE|BASE_VAL64_STRING0x00000400, "BASE_NONE|BASE_VAL64_STRING" },
9363 | { BASE_DEC|BASE_VAL64_STRING0x00000400, "BASE_DEC|BASE_VAL64_STRING" },
9364 | { BASE_HEX|BASE_VAL64_STRING0x00000400, "BASE_HEX|BASE_VAL64_STRING" },
9365 | { BASE_OCT|BASE_VAL64_STRING0x00000400, "BASE_OCT|BASE_VAL64_STRING" },
9366 | { BASE_DEC_HEX|BASE_VAL64_STRING0x00000400, "BASE_DEC_HEX|BASE_VAL64_STRING" },
9367 | { BASE_HEX_DEC|BASE_VAL64_STRING0x00000400, "BASE_HEX_DEC|BASE_VAL64_STRING" },
9368 | { BASE_CUSTOM|BASE_VAL64_STRING0x00000400, "BASE_CUSTOM|BASE_VAL64_STRING" },
9369 | { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
9370 | { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
9371 | { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
9372 | { BASE_PT_UDP, "BASE_PT_UDP" },
9373 | { BASE_PT_TCP, "BASE_PT_TCP" },
9374 | { BASE_PT_DCCP, "BASE_PT_DCCP" },
9375 | { BASE_PT_SCTP, "BASE_PT_SCTP" },
9376 | { BASE_OUI, "BASE_OUI" },
9377 | { 0, NULL((void*)0) } };
9378 |
9379 | const char* proto_field_display_to_string(int field_display)
9380 | {
9381 | return val_to_str_const(field_display, hf_display, "Unknown");
9382 | }
9383 |
9384 | static inline port_type
9385 | display_to_port_type(field_display_e e)
9386 | {
9387 | switch (e) {
9388 | case BASE_PT_UDP:
9389 | return PT_UDP;
9390 | case BASE_PT_TCP:
9391 | return PT_TCP;
9392 | case BASE_PT_DCCP:
9393 | return PT_DCCP;
9394 | case BASE_PT_SCTP:
9395 | return PT_SCTP;
9396 | default:
9397 | break;
9398 | }
9399 | return PT_NONE;
9400 | }
9401 |
9402 | /* temporary function containing assert part for easier profiling */
9403 | static void
9404 | tmp_fld_check_assert(header_field_info *hfinfo)
9405 | {
9406 | char* tmp_str;
9407 |
9408 | /* The field must have a name (with length > 0) */
9409 | if (!hfinfo->name || !hfinfo->name[0]) {
9410 | if (hfinfo->abbrev)
9411 | /* Try to identify the field */
9412 | 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)
9413 | hfinfo->abbrev)proto_report_dissector_bug("Field (abbrev='%s') does not have a name" , hfinfo->abbrev);
9414 | else
9415 | /* Hum, no luck */
9416 | 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)" );
9417 | }
9418 |
9419 | /* fields with an empty string for an abbreviation aren't filterable */
9420 | if (!hfinfo->abbrev || !hfinfo->abbrev[0])
9421 | 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);
9422 |
9423 | /* TODO: This check is a significant percentage of startup time (~10%),
9424 | although not nearly as slow as what's enabled by ENABLE_CHECK_FILTER.
9425 | It might be nice to have a way to disable this check when, e.g.,
9426 | running TShark many times with the same configuration. */
9427 | /* Check that the filter name (abbreviation) is legal;
9428 | * it must contain only alphanumerics, '-', "_", and ".". */
9429 | unsigned char c;
9430 | c = module_check_valid_name(hfinfo->abbrev, false0);
9431 | if (c) {
9432 | if (c == '.') {
9433 | 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);
9434 | } else if (g_ascii_isprint(c)((g_ascii_table[(guchar) (c)] & G_ASCII_PRINT) != 0)) {
9435 | 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);
9436 | } else {
9437 | 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);
9438 | }
9439 | }
9440 |
9441 | /* These types of fields are allowed to have value_strings,
9442 | * true_false_strings or a protocol_t struct
9443 | */
9444 | if (hfinfo->strings != NULL((void*)0) && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM) {
9445 | switch (hfinfo->type) {
9446 |
9447 | /*
9448 | * These types are allowed to support display value_strings,
9449 | * value64_strings, the extended versions of the previous
9450 | * two, range strings, or unit strings.
9451 | */
9452 | case FT_CHAR:
9453 | case FT_UINT8:
9454 | case FT_UINT16:
9455 | case FT_UINT24:
9456 | case FT_UINT32:
9457 | case FT_UINT40:
9458 | case FT_UINT48:
9459 | case FT_UINT56:
9460 | case FT_UINT64:
9461 | case FT_INT8:
9462 | case FT_INT16:
9463 | case FT_INT24:
9464 | case FT_INT32:
9465 | case FT_INT40:
9466 | case FT_INT48:
9467 | case FT_INT56:
9468 | case FT_INT64:
9469 | case FT_BOOLEAN:
9470 | case FT_PROTOCOL:
9471 | break;
9472 |
9473 | /*
9474 | * This is allowed to have a value of type
9475 | * enum ft_framenum_type to indicate what relationship
9476 | * the frame in question has to the frame in which
9477 | * the field is put.
9478 | */
9479 | case FT_FRAMENUM:
9480 | break;
9481 |
9482 | /*
9483 | * These types are allowed to support only unit strings.
9484 | */
9485 | case FT_FLOAT:
9486 | case FT_DOUBLE:
9487 | case FT_IEEE_11073_SFLOAT:
9488 | case FT_IEEE_11073_FLOAT:
9489 | if (!(hfinfo->display & BASE_UNIT_STRING0x00001000)) {
9490 | 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))
9491 | " (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))
9492 | 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));
9493 | }
9494 | break;
9495 |
9496 | /*
9497 | * These types are allowed to support display
9498 | * time_value_strings.
9499 | */
9500 | case FT_ABSOLUTE_TIME:
9501 | if (hfinfo->display & BASE_RANGE_STRING0x00000100 ||
9502 | hfinfo->display & BASE_EXT_STRING0x00000200 ||
9503 | hfinfo->display & BASE_VAL64_STRING0x00000400 ||
9504 | hfinfo->display & BASE_UNIT_STRING0x00001000) {
9505 | 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))
9506 | " (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))
9507 | 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));
9508 | }
9509 | break;
9510 |
9511 | /*
9512 | * This type is only allowed to support a string if it's
9513 | * a protocol (for pinos).
9514 | */
9515 | case FT_BYTES:
9516 | if (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)) {
9517 | 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))
9518 | " (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))
9519 | 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));
9520 | }
9521 | break;
9522 |
9523 | default:
9524 | 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))
9525 | " (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))
9526 | 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));
9527 | }
9528 | }
9529 |
9530 | /* TODO: This check may slow down startup, and output quite a few warnings.
9531 | It would be good to be able to enable this (and possibly other checks?)
9532 | in non-release builds. */
9533 | #ifdef ENABLE_CHECK_FILTER
9534 | /* Check for duplicate value_string values.
9535 | There are lots that have the same value *and* string, so for now only
9536 | report those that have same value but different string. */
9537 | if ((hfinfo->strings != NULL((void*)0)) &&
9538 | !(hfinfo->display & BASE_RANGE_STRING0x00000100) &&
9539 | !(hfinfo->display & BASE_UNIT_STRING0x00001000) &&
9540 | !((hfinfo->display & FIELD_DISPLAY_E_MASK0xFF) == BASE_CUSTOM) &&
9541 | (
9542 | (hfinfo->type == FT_CHAR) ||
9543 | (hfinfo->type == FT_UINT8) ||
9544 | (hfinfo->type == FT_UINT16) ||
9545 | (hfinfo->type == FT_UINT24) ||
9546 | (hfinfo->type == FT_UINT32) ||
9547 | (hfinfo->type == FT_INT8) ||
9548 | (hfinfo->type == FT_INT16) ||
9549 | (hfinfo->type == FT_INT24) ||
9550 | (hfinfo->type == FT_INT32) )) {
9551 |
9552 | if (hfinfo->display & BASE_EXT_STRING0x00000200) {
9553 | if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
9554 | const val64_string *start_values = VAL64_STRING_EXT_VS_P((const val64_string_ext*)hfinfo->strings)((const val64_string_ext*)hfinfo->strings)->_vs_p;
9555 | CHECK_HF_VALUE(val64_string, PRIu64"l" "u", start_values);
9556 | } else {
9557 | const value_string *start_values = VALUE_STRING_EXT_VS_P((const value_string_ext*)hfinfo->strings)((const value_string_ext*)hfinfo->strings)->_vs_p;
9558 | CHECK_HF_VALUE(value_string, "u", start_values);
9559 | }
9560 | } else {
9561 | const value_string *start_values = (const value_string*)hfinfo->strings;
9562 | CHECK_HF_VALUE(value_string, "u", start_values);
9563 | }
9564 | }
9565 |
9566 | if (hfinfo->type == FT_BOOLEAN) {
9567 | const true_false_string *tfs = (const true_false_string*)hfinfo->strings;
9568 | if (tfs) {
9569 | if (strcmp(tfs->false_string, tfs->true_string) == 0) {
9570 | ws_error("Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")",ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9572 , __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")" , hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs ->true_string)
9571 | hfinfo->name, hfinfo->abbrev,ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9572 , __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")" , hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs ->true_string)
9572 | tfs->false_string, tfs->true_string)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9572 , __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")" , hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs ->true_string);
9573 | }
9574 | }
9575 | }
9576 |
9577 | if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
9578 | const range_string *rs = (const range_string*)(hfinfo->strings);
9579 | if (rs) {
9580 | const range_string *this_it = rs;
9581 |
9582 | do {
9583 | if (this_it->value_max < this_it->value_min) {
9584 | 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" , 9588, __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)
9585 | hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9588, __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)
9586 | this_it->strptr,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9588, __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)
9587 | this_it->value_max, this_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9588, __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)
9588 | this_it->value_min, this_it->value_min)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9588, __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);
9589 | ++this_it;
9590 | continue;
9591 | }
9592 |
9593 | for (const range_string *prev_it=rs; prev_it < this_it; ++prev_it) {
9594 | /* Not OK if this one is completely hidden by an earlier one! */
9595 | if ((prev_it->value_min <= this_it->value_min) && (prev_it->value_max >= this_it->value_max)) {
9596 | 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" , 9602, __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)
9597 | "(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" , 9602, __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)
9598 | hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9602, __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)
9599 | prev_it->strptr, prev_it->value_min, prev_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9602, __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)
9600 | prev_it->value_max, prev_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9602, __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)
9601 | this_it->strptr, this_it->value_min, this_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9602, __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)
9602 | this_it->value_max, this_it->value_max)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9602, __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);
9603 | }
9604 | }
9605 | ++this_it;
9606 | } while (this_it->strptr);
9607 | }
9608 | }
9609 | #endif
9610 |
9611 | switch (hfinfo->type) {
9612 |
9613 | case FT_CHAR:
9614 | /* Require the char type to have BASE_HEX, BASE_OCT,
9615 | * BASE_CUSTOM, or BASE_NONE as its base.
9616 | *
9617 | * If the display value is BASE_NONE and there is a
9618 | * strings conversion then the dissector writer is
9619 | * telling us that the field's numerical value is
9620 | * meaningless; we'll avoid showing the value to the
9621 | * user.
9622 | */
9623 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9624 | case BASE_HEX:
9625 | case BASE_OCT:
9626 | case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9627 | break;
9628 | case BASE_NONE:
9629 | if (hfinfo->strings == NULL((void*)0))
9630 | 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 ))
9631 | " 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 ))
9632 | " 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 ))
9633 | 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 ))
9634 | 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 ));
9635 | break;
9636 | default:
9637 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9638 | 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)
9639 | " 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)
9640 | 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)
9641 | 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);
9642 | //wmem_free(NULL, tmp_str);
9643 | }
9644 | if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
9645 | 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 ))
9646 | 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 ))
9647 | 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 ));
9648 | }
9649 | break;
9650 | case FT_INT8:
9651 | case FT_INT16:
9652 | case FT_INT24:
9653 | case FT_INT32:
9654 | case FT_INT40:
9655 | case FT_INT48:
9656 | case FT_INT56:
9657 | case FT_INT64:
9658 | /* Hexadecimal and octal are, in printf() and everywhere
9659 | * else, unsigned so don't allow dissectors to register a
9660 | * signed field to be displayed unsigned. (Else how would
9661 | * we display negative values?)
9662 | */
9663 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9664 | case BASE_HEX:
9665 | case BASE_OCT:
9666 | case BASE_DEC_HEX:
9667 | case BASE_HEX_DEC:
9668 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9669 | 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)
9670 | 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)
9671 | 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);
9672 | //wmem_free(NULL, tmp_str);
9673 | }
9674 | /* FALL THROUGH */
9675 | case FT_UINT8:
9676 | case FT_UINT16:
9677 | case FT_UINT24:
9678 | case FT_UINT32:
9679 | case FT_UINT40:
9680 | case FT_UINT48:
9681 | case FT_UINT56:
9682 | case FT_UINT64:
9683 | 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 ))) {
9684 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9685 | if (hfinfo->type != FT_UINT16) {
9686 | 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))
9687 | 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))
9688 | 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));
9689 | }
9690 | if (hfinfo->strings != NULL((void*)0)) {
9691 | 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)
9692 | 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)
9693 | 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);
9694 | }
9695 | if (hfinfo->bitmask != 0) {
9696 | 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)
9697 | 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)
9698 | 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);
9699 | }
9700 | wmem_free(NULL((void*)0), tmp_str);
9701 | break;
9702 | }
9703 |
9704 | if (hfinfo->display == BASE_OUI) {
9705 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9706 | if (!FT_IS_UINT(hfinfo->type)(((hfinfo->type) == FT_CHAR || (hfinfo->type) == FT_UINT8 || (hfinfo->type) == FT_UINT16 || (hfinfo->type) == FT_UINT24 || (hfinfo->type) == FT_UINT32 || (hfinfo->type) == FT_FRAMENUM ) || ((hfinfo->type) == FT_UINT40 || (hfinfo->type) == FT_UINT48 || (hfinfo->type) == FT_UINT56 || (hfinfo->type) == FT_UINT64 )) || ftype_wire_size(hfinfo->type) < 3) {
9707 | 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))
9708 | 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))
9709 | tmp_str, ftype_name(hfinfo->type))proto_report_dissector_bug("Field '%s' (%s) has 'display' value %s but it can only be used with FT_UINT24, not %s" , hfinfo->name, hfinfo->abbrev, tmp_str, ftype_name(hfinfo ->type));
9710 | }
9711 | if (hfinfo->strings != NULL((void*)0)) {
9712 | REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s (%s) but has a strings value",proto_report_dissector_bug("Field '%s' (%s) is an %s (%s) but has a strings value" , hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type ), tmp_str)
9713 | hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is an %s (%s) but has a strings value" , hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type ), tmp_str)
9714 | ftype_name(hfinfo->type), tmp_str)proto_report_dissector_bug("Field '%s' (%s) is an %s (%s) but has a strings value" , hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type ), tmp_str);
9715 | }
9716 | /* It can be a FT_UINT24 with a 0 bitmask, or
9717 | * larger with a bitmask with 24 bits set. */
9718 | if ((hfinfo->type != FT_UINT24 || hfinfo->bitmask != 0) && ws_count_ones(hfinfo->bitmask) != 24) {
9719 | 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)
9720 | 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)
9721 | 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);
9722 | }
9723 | wmem_free(NULL((void*)0), tmp_str);
9724 | break;
9725 | }
9726 |
9727 | /* Require integral types (other than frame number,
9728 | * which is always displayed in decimal) to have a
9729 | * number base.
9730 | *
9731 | * If the display value is BASE_NONE and there is a
9732 | * strings conversion then the dissector writer is
9733 | * telling us that the field's numerical value is
9734 | * meaningless; we'll avoid showing the value to the
9735 | * user.
9736 | */
9737 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9738 | case BASE_DEC:
9739 | case BASE_HEX:
9740 | case BASE_OCT:
9741 | case BASE_DEC_HEX:
9742 | case BASE_HEX_DEC:
9743 | case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9744 | break;
9745 | case BASE_NONE:
9746 | if (hfinfo->strings == NULL((void*)0)) {
9747 | 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 ))
9748 | " 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 ))
9749 | " 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 ))
9750 | 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 ))
9751 | 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 ));
9752 | }
9753 | if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
9754 | 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 ))
9755 | " 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 ))
9756 | " 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 ))
9757 | 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 ))
9758 | 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 ));
9759 | }
9760 | break;
9761 |
9762 | default:
9763 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9764 | 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)
9765 | " 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)
9766 | 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)
9767 | 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);
9768 | //wmem_free(NULL, tmp_str);
9769 | }
9770 | break;
9771 | case FT_BYTES:
9772 | case FT_UINT_BYTES:
9773 | /* Require bytes to have a "display type" that could
9774 | * add a character between displayed bytes.
9775 | */
9776 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9777 | case BASE_NONE:
9778 | case SEP_DOT:
9779 | case SEP_DASH:
9780 | case SEP_COLON:
9781 | case SEP_SPACE:
9782 | break;
9783 | default:
9784 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9785 | 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)
9786 | 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);
9787 | //wmem_free(NULL, tmp_str);
9788 | }
9789 | if (hfinfo->bitmask != 0)
9790 | 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 ))
9791 | 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 ))
9792 | 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 ));
9793 | //allowed to support string if its a protocol (for pinos)
9794 | if ((hfinfo->strings != NULL((void*)0)) && (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)))
9795 | 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 ))
9796 | 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 ))
9797 | 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 ));
9798 | break;
9799 |
9800 | case FT_PROTOCOL:
9801 | case FT_FRAMENUM:
9802 | if (hfinfo->display != BASE_NONE) {
9803 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9804 | 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)
9805 | 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)
9806 | 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);
9807 | //wmem_free(NULL, tmp_str);
9808 | }
9809 | if (hfinfo->bitmask != 0)
9810 | 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 ))
9811 | 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 ))
9812 | 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 ));
9813 | break;
9814 |
9815 | case FT_BOOLEAN:
9816 | break;
9817 |
9818 | case FT_ABSOLUTE_TIME:
9819 | if (!FIELD_DISPLAY_IS_ABSOLUTE_TIME(hfinfo->display)(((hfinfo->display) & 0xFF) >= ABSOLUTE_TIME_LOCAL && ((hfinfo->display) & 0xFF) <= ABSOLUTE_TIME_UNIX)) {
9820 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9821 | 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)
9822 | 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);
9823 | //wmem_free(NULL, tmp_str);
9824 | }
9825 | if (hfinfo->bitmask != 0)
9826 | 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 ))
9827 | 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 ))
9828 | 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 ));
9829 | break;
9830 |
9831 | case FT_STRING:
9832 | case FT_STRINGZ:
9833 | case FT_UINT_STRING:
9834 | case FT_STRINGZPAD:
9835 | case FT_STRINGZTRUNC:
9836 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9837 | case BASE_NONE:
9838 | case BASE_STR_WSP:
9839 | break;
9840 |
9841 | default:
9842 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9843 | 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)
9844 | " 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)
9845 | 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)
9846 | 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);
9847 | //wmem_free(NULL, tmp_str);
9848 | }
9849 |
9850 | if (hfinfo->bitmask != 0)
9851 | 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 ))
9852 | 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 ))
9853 | 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 ));
9854 | if (hfinfo->strings != NULL((void*)0))
9855 | 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 ))
9856 | 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 ))
9857 | 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 ));
9858 | break;
9859 |
9860 | case FT_IPv4:
9861 | switch (hfinfo->display) {
9862 | case BASE_NONE:
9863 | case BASE_NETMASK:
9864 | break;
9865 |
9866 | default:
9867 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9868 | 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)
9869 | " 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)
9870 | 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)
9871 | 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);
9872 | //wmem_free(NULL, tmp_str);
9873 | break;
9874 | }
9875 | break;
9876 | case FT_FLOAT:
9877 | case FT_DOUBLE:
9878 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9879 | case BASE_NONE:
9880 | case BASE_DEC:
9881 | case BASE_HEX:
9882 | case BASE_EXP:
9883 | case BASE_CUSTOM:
9884 | break;
9885 | default:
9886 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9887 | 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)
9888 | " 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)
9889 | 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)
9890 | 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);
9891 | //wmem_free(NULL, tmp_str);
9892 | }
9893 | if (hfinfo->bitmask != 0)
9894 | 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 ))
9895 | 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 ))
9896 | 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 ));
9897 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM && (hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9898 | 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 ))
9899 | 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 ))
9900 | 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 ));
9901 | break;
9902 | case FT_IEEE_11073_SFLOAT:
9903 | case FT_IEEE_11073_FLOAT:
9904 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_NONE) {
9905 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9906 | 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)
9907 | 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)
9908 | 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)
9909 | 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);
9910 | //wmem_free(NULL, tmp_str);
9911 | }
9912 | if (hfinfo->bitmask != 0)
9913 | 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 ))
9914 | 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 ))
9915 | 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 ));
9916 | if ((hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9917 | 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 ))
9918 | 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 ))
9919 | 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 ));
9920 | break;
9921 | default:
9922 | if (hfinfo->display != BASE_NONE) {
9923 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9924 | 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)
9925 | 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)
9926 | 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)
9927 | 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);
9928 | //wmem_free(NULL, tmp_str);
9929 | }
9930 | if (hfinfo->bitmask != 0)
9931 | 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 ))
9932 | 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 ))
9933 | 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 ));
9934 | if (hfinfo->strings != NULL((void*)0))
9935 | 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 ))
9936 | 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 ))
9937 | 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 ));
9938 | break;
9939 | }
9940 | }
9941 |
9942 | static void
9943 | register_type_length_mismatch(void)
9944 | {
9945 | static ei_register_info ei[] = {
9946 | { &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)}} }},
9947 | { &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)}} }},
9948 | };
9949 |
9950 | expert_module_t* expert_type_length_mismatch;
9951 |
9952 | proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
9953 |
9954 | expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
9955 | expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9956 |
9957 | /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
9958 | disabling them makes no sense. */
9959 | proto_set_cant_toggle(proto_type_length_mismatch);
9960 | }
9961 |
9962 | static void
9963 | register_byte_array_string_decodinws_error(void)
9964 | {
9965 | static ei_register_info ei[] = {
9966 | { &ei_byte_array_string_decoding_failed_error,
9967 | { "_ws.byte_array_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9968 | "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)}}
9969 | }
9970 | },
9971 | };
9972 |
9973 | expert_module_t* expert_byte_array_string_decoding_error;
9974 |
9975 | proto_byte_array_string_decoding_error =
9976 | proto_register_protocol("Byte Array-String Decoding Error",
9977 | "Byte Array-string decoding error",
9978 | "_ws.byte_array_string.decoding_error");
9979 |
9980 | expert_byte_array_string_decoding_error =
9981 | expert_register_protocol(proto_byte_array_string_decoding_error);
9982 | expert_register_field_array(expert_byte_array_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9983 |
9984 | /* "Byte Array-String Decoding Error" isn't really a protocol, it's an error indication;
9985 | disabling them makes no sense. */
9986 | proto_set_cant_toggle(proto_byte_array_string_decoding_error);
9987 | }
9988 |
9989 | static void
9990 | register_date_time_string_decodinws_error(void)
9991 | {
9992 | static ei_register_info ei[] = {
9993 | { &ei_date_time_string_decoding_failed_error,
9994 | { "_ws.date_time_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9995 | "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)}}
9996 | }
9997 | },
9998 | };
9999 |
10000 | expert_module_t* expert_date_time_string_decoding_error;
10001 |
10002 | proto_date_time_string_decoding_error =
10003 | proto_register_protocol("Date and Time-String Decoding Error",
10004 | "Date and Time-string decoding error",
10005 | "_ws.date_time_string.decoding_error");
10006 |
10007 | expert_date_time_string_decoding_error =
10008 | expert_register_protocol(proto_date_time_string_decoding_error);
10009 | expert_register_field_array(expert_date_time_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10010 |
10011 | /* "Date and Time-String Decoding Error" isn't really a protocol, it's an error indication;
10012 | disabling them makes no sense. */
10013 | proto_set_cant_toggle(proto_date_time_string_decoding_error);
10014 | }
10015 |
10016 | static void
10017 | register_string_errors(void)
10018 | {
10019 | static ei_register_info ei[] = {
10020 | { &ei_string_trailing_characters,
10021 | { "_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)}} }
10022 | },
10023 | };
10024 |
10025 | expert_module_t* expert_string_errors;
10026 |
10027 | proto_string_errors = proto_register_protocol("String Errors", "String errors", "_ws.string");
10028 |
10029 | expert_string_errors = expert_register_protocol(proto_string_errors);
10030 | expert_register_field_array(expert_string_errors, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10031 |
10032 | /* "String Errors" isn't really a protocol, it's an error indication;
10033 | disabling them makes no sense. */
10034 | proto_set_cant_toggle(proto_string_errors);
10035 | }
10036 |
10037 | static int
10038 | proto_register_field_init(header_field_info *hfinfo, const int parent)
10039 | {
10040 |
10041 | tmp_fld_check_assert(hfinfo);
10042 |
10043 | hfinfo->parent = parent;
10044 | hfinfo->same_name_next = NULL((void*)0);
10045 | hfinfo->same_name_prev_id = -1;
10046 |
10047 | /* if we always add and never delete, then id == len - 1 is correct */
10048 | if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
10049 | if (!gpa_hfinfo.hfi) {
10050 | gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000);
10051 | gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
10052 | /* The entry with index 0 is not used. */
10053 | gpa_hfinfo.hfi[0] = NULL((void*)0);
10054 | gpa_hfinfo.len = 1;
10055 | } else {
10056 | gpa_hfinfo.allocated_len += 1000;
10057 | gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
10058 | sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
10059 | /*ws_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
10060 | }
10061 | }
10062 | gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
10063 | gpa_hfinfo.len++;
10064 | hfinfo->id = gpa_hfinfo.len - 1;
10065 |
10066 | /* if we have real names, enter this field in the name tree */
10067 | /* Already checked in tmp_fld_check_assert */
10068 | /*if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) */
10069 | {
10070 |
10071 | header_field_info *same_name_next_hfinfo;
10072 |
10073 | /* We allow multiple hfinfo's to be registered under the same
10074 | * abbreviation. This was done for X.25, as, depending
10075 | * on whether it's modulo-8 or modulo-128 operation,
10076 | * some bitfield fields may be in different bits of
10077 | * a byte, and we want to be able to refer to that field
10078 | * with one name regardless of whether the packets
10079 | * are modulo-8 or modulo-128 packets. */
10080 |
10081 | /* wmem_map_insert - if key is already present the previous
10082 | * hfinfo with the same key/name is returned, otherwise NULL */
10083 | same_name_hfinfo = wmem_map_insert(gpa_name_map, (void *) (hfinfo->abbrev), hfinfo);
10084 | if (same_name_hfinfo) {
10085 | /* There's already a field with this name.
10086 | * Put the current field *before* that field
10087 | * in the list of fields with this name, Thus,
10088 | * we end up with an effectively
10089 | * doubly-linked-list of same-named hfinfo's,
10090 | * with the head of the list (stored in the
10091 | * hash) being the last seen hfinfo.
10092 | */
10093 | same_name_next_hfinfo =
10094 | same_name_hfinfo->same_name_next;
10095 |
10096 | hfinfo->same_name_next = same_name_next_hfinfo;
10097 | if (same_name_next_hfinfo)
10098 | same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
10099 |
10100 | same_name_hfinfo->same_name_next = hfinfo;
10101 | hfinfo->same_name_prev_id = same_name_hfinfo->id;
10102 | #ifdef ENABLE_CHECK_FILTER
10103 | while (same_name_hfinfo) {
10104 | if (!ftype_similar_types(hfinfo->type, same_name_hfinfo->type))
10105 | 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", 10105 , __func__, "'%s' exists multiple times with incompatible types: %s and %s" , hfinfo->abbrev, ftype_name(hfinfo->type), ftype_name( same_name_hfinfo->type));
10106 | same_name_hfinfo = same_name_hfinfo->same_name_next;
10107 | }
10108 | #endif
10109 | }
10110 | }
10111 |
10112 | return hfinfo->id;
10113 | }
10114 |
10115 | void
10116 | proto_register_subtree_array(int * const *indices, const int num_indices)
10117 | {
10118 | int i;
10119 | int *const *ptr = indices;
10120 |
10121 | /*
10122 | * If we've already allocated the array of tree types, expand
10123 | * it; this lets plugins such as mate add tree types after
10124 | * the initial startup. (If we haven't already allocated it,
10125 | * we don't allocate it; on the first pass, we just assign
10126 | * ett values and keep track of how many we've assigned, and
10127 | * when we're finished registering all dissectors we allocate
10128 | * the array, so that we do only one allocation rather than
10129 | * wasting CPU time and memory by growing the array for each
10130 | * dissector that registers ett values.)
10131 | */
10132 | if (tree_is_expanded != NULL((void*)0)) {
10133 | tree_is_expanded = (uint32_t *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(uint32_t));
10134 |
10135 | /* set new items to 0 */
10136 | /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of uint32_t to 0) */
10137 | for (i = num_tree_types; i < num_tree_types + num_indices; i++)
10138 | tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
10139 | }
10140 |
10141 | /*
10142 | * Assign "num_indices" subtree numbers starting at "num_tree_types",
10143 | * returning the indices through the pointers in the array whose
10144 | * first element is pointed to by "indices", and update
10145 | * "num_tree_types" appropriately.
10146 | */
10147 | for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
10148 | if (**ptr != -1 && **ptr != 0) {
10149 | 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.")
10150 | " 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.")
10151 | " 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.")
10152 | " 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.");
10153 | }
10154 | **ptr = num_tree_types;
10155 | }
10156 | }
10157 |
10158 | static void
10159 | mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos)
10160 | {
10161 | static const char trunc_str[] = " [" UTF8_HORIZONTAL_ELLIPSIS"\u2026" "] ";
10162 | const size_t trunc_len = sizeof(trunc_str)-2; /* Default do not include the trailing space. */
10163 | char *last_char;
10164 |
10165 | /* ..... field_name: dataaaaaaaaaaaaa
10166 | * |
10167 | * ^^^^^ name_pos
10168 | *
10169 | * ..... field_name […]: dataaaaaaaaaaaaa
10170 | *
10171 | * name_pos==0 means that we have only data or only a field_name
10172 | */
10173 |
10174 | ws_abort_if_fail(size > trunc_len)do { if ((1) && !(size > trunc_len)) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10174, __func__, "assertion failed: %s" , "size > trunc_len"); } while (0);
10175 |
10176 | if (name_pos >= size - trunc_len) {
10177 | /* No room for trunc_str after the field_name, put it first. */
10178 | name_pos = 0;
10179 | }
10180 |
10181 | memmove(label_str + name_pos + trunc_len, label_str + name_pos, size - name_pos - trunc_len);
10182 | if (name_pos == 0) {
10183 | /* Copy the trunc_str after the first byte, so that we don't have a leading space in the label. */
10184 | memcpy(label_str, trunc_str + 1, trunc_len);
10185 | } else {
10186 | memcpy(label_str + name_pos, trunc_str, trunc_len);
10187 | }
10188 | /* in general, label_str is UTF-8
10189 | we can truncate it only at the beginning of a new character
10190 | we go backwards from the byte right after our buffer and
10191 | find the next starting byte of a UTF-8 character, this is
10192 | where we cut
10193 | there's no need to use g_utf8_find_prev_char(), the search
10194 | will always succeed since we copied trunc_str into the
10195 | buffer */
10196 | /* g_utf8_prev_char does not deference the memory address
10197 | * passed in (until after decrementing it, so it is perfectly
10198 | * legal to pass in a pointer one past the last element.
10199 | */
10200 | last_char = g_utf8_prev_char(label_str + size);
10201 | *last_char = '\0';
10202 | /* This is unnecessary (above always terminates), but try to
10203 | * convince Coverity to avoid dozens of false positives. */
10204 | label_str[size - 1] = '\0';
10205 |
10206 | if (value_pos && *value_pos > 0) {
10207 | if (name_pos == 0) {
10208 | *value_pos += trunc_len;
10209 | } else {
10210 | /* Move one back to include trunc_str in the value. */
10211 | *value_pos -= 1;
10212 | }
10213 | }
10214 |
10215 | /* Check if value_pos is past label_str. */
10216 | if (value_pos && *value_pos >= size) {
10217 | *value_pos = size - 1;
10218 | }
10219 | }
10220 |
10221 | static void
10222 | label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos)
10223 | {
10224 | mark_truncated(label_str, name_pos, ITEM_LABEL_LENGTH240, value_pos);
10225 | }
10226 |
10227 | static size_t
10228 | label_fill(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, size_t *value_pos)
10229 | {
10230 | size_t name_pos;
10231 |
10232 | /* "%s: %s", hfinfo->name, text */
10233 | 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);
10234 | if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10235 | pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10236 | if (value_pos) {
10237 | *value_pos = pos;
10238 | }
10239 | pos = ws_label_strcpy(label_str, ITEM_LABEL_LENGTH240, pos, (const uint8_t*)(text ? text : "(null)"), label_strcat_flags(hfinfo));
10240 | }
10241 |
10242 | if (pos >= ITEM_LABEL_LENGTH240) {
10243 | /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10244 | label_mark_truncated(label_str, name_pos, value_pos);
10245 | }
10246 |
10247 | return pos;
10248 | }
10249 |
10250 | static size_t
10251 | label_fill_descr(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, const char *descr, size_t *value_pos)
10252 | {
10253 | size_t name_pos;
10254 |
10255 | /* "%s: %s (%s)", hfinfo->name, text, descr */
10256 | 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);
10257 | if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10258 | pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10259 | if (value_pos) {
10260 | *value_pos = pos;
10261 | }
10262 | if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
10263 | 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);
10264 | 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);
10265 | } else {
10266 | 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);
10267 | pos = label_concat(label_str, pos, (const uint8_t*)" (")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)" (", 0);
10268 | 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);
10269 | pos = label_concat(label_str, pos, (const uint8_t*)")")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)")", 0);
10270 | }
10271 | }
10272 |
10273 | if (pos >= ITEM_LABEL_LENGTH240) {
10274 | /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10275 | label_mark_truncated(label_str, name_pos, value_pos);
10276 | }
10277 |
10278 | return pos;
10279 | }
10280 |
10281 | void
10282 | proto_item_fill_label(const field_info *fi, char *label_str, size_t *value_pos)
10283 | {
10284 | const header_field_info *hfinfo;
10285 | const char *str;
10286 | const uint8_t *bytes;
10287 | uint32_t integer;
10288 | const ipv4_addr_and_mask *ipv4;
10289 | const ipv6_addr_and_prefix *ipv6;
10290 | const e_guid_t *guid;
10291 | char *name;
10292 | address addr;
10293 | char *addr_str;
10294 | char *tmp;
10295 |
10296 | if (!label_str) {
10297 | ws_warning("NULL label_str passed to proto_item_fill_label.")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 10297, __func__, "NULL label_str passed to proto_item_fill_label." ); } } while (0);
10298 | return;
10299 | }
10300 |
10301 | label_str[0]= '\0';
10302 |
10303 | if (!fi) {
10304 | return;
10305 | }
10306 |
10307 | hfinfo = fi->hfinfo;
10308 |
10309 | switch (hfinfo->type) {
10310 | case FT_NONE:
10311 | case FT_PROTOCOL:
10312 | (void) g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH240);
10313 | if (value_pos) {
10314 | *value_pos = strlen(hfinfo->name);
10315 | }
10316 | break;
10317 |
10318 | case FT_BOOLEAN:
10319 | fill_label_boolean(fi, label_str, value_pos);
10320 | break;
10321 |
10322 | case FT_BYTES:
10323 | case FT_UINT_BYTES:
10324 | tmp = format_bytes_hfinfo(NULL((void*)0), hfinfo,
10325 | fvalue_get_bytes_data(fi->value),
10326 | (unsigned)fvalue_length2(fi->value));
10327 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10328 | wmem_free(NULL((void*)0), tmp);
10329 | break;
10330 |
10331 | case FT_CHAR:
10332 | if (hfinfo->bitmask) {
10333 | fill_label_bitfield_char(fi, label_str, value_pos);
10334 | } else {
10335 | fill_label_char(fi, label_str, value_pos);
10336 | }
10337 | break;
10338 |
10339 | /* Four types of integers to take care of:
10340 | * Bitfield, with val_string
10341 | * Bitfield, w/o val_string
10342 | * Non-bitfield, with val_string
10343 | * Non-bitfield, w/o val_string
10344 | */
10345 | case FT_UINT8:
10346 | case FT_UINT16:
10347 | case FT_UINT24:
10348 | case FT_UINT32:
10349 | if (hfinfo->bitmask) {
10350 | fill_label_bitfield(fi, label_str, value_pos, false0);
10351 | } else {
10352 | fill_label_number(fi, label_str, value_pos, false0);
10353 | }
10354 | break;
10355 |
10356 | case FT_FRAMENUM:
10357 | fill_label_number(fi, label_str, value_pos, false0);
10358 | break;
10359 |
10360 | case FT_UINT40:
10361 | case FT_UINT48:
10362 | case FT_UINT56:
10363 | case FT_UINT64:
10364 | if (hfinfo->bitmask) {
10365 | fill_label_bitfield64(fi, label_str, value_pos, false0);
10366 | } else {
10367 | fill_label_number64(fi, label_str, value_pos, false0);
10368 | }
10369 | break;
10370 |
10371 | case FT_INT8:
10372 | case FT_INT16:
10373 | case FT_INT24:
10374 | case FT_INT32:
10375 | if (hfinfo->bitmask) {
10376 | fill_label_bitfield(fi, label_str, value_pos, true1);
10377 | } else {
10378 | fill_label_number(fi, label_str, value_pos, true1);
10379 | }
10380 | break;
10381 |
10382 | case FT_INT40:
10383 | case FT_INT48:
10384 | case FT_INT56:
10385 | case FT_INT64:
10386 | if (hfinfo->bitmask) {
10387 | fill_label_bitfield64(fi, label_str, value_pos, true1);
10388 | } else {
10389 | fill_label_number64(fi, label_str, value_pos, true1);
10390 | }
10391 | break;
10392 |
10393 | case FT_FLOAT:
10394 | case FT_DOUBLE:
10395 | fill_label_float(fi, label_str, value_pos);
10396 | break;
10397 |
10398 | case FT_ABSOLUTE_TIME:
10399 | {
10400 | const nstime_t *value = fvalue_get_time(fi->value);
10401 | int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
10402 | if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
10403 | flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
10404 | }
10405 | if (hfinfo->strings) {
10406 | /*
10407 | * Table of time valus to be displayed
10408 | * specially.
10409 | */
10410 | const char *time_string = try_time_val_to_str(value, (const time_value_string *)hfinfo->strings);
10411 | if (time_string != NULL((void*)0)) {
10412 | label_fill(label_str, 0, hfinfo, time_string, value_pos);
10413 | break;
10414 | }
10415 | }
10416 | tmp = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
10417 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10418 | wmem_free(NULL((void*)0), tmp);
10419 | break;
10420 | }
10421 | case FT_RELATIVE_TIME:
10422 | tmp = rel_time_to_str(NULL((void*)0), fvalue_get_time(fi->value));
10423 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10424 | wmem_free(NULL((void*)0), tmp);
10425 | break;
10426 |
10427 | case FT_IPXNET:
10428 | integer = fvalue_get_uinteger(fi->value);
10429 | tmp = get_ipxnet_name(NULL((void*)0), integer);
10430 | addr_str = wmem_strdup_printf(NULL((void*)0), "0x%08X", integer);
10431 | label_fill_descr(label_str, 0, hfinfo, tmp, addr_str, value_pos);
10432 | wmem_free(NULL((void*)0), tmp);
10433 | wmem_free(NULL((void*)0), addr_str);
10434 | break;
10435 |
10436 | case FT_VINES:
10437 | addr.type = AT_VINES;
10438 | addr.len = VINES_ADDR_LEN6;
10439 | addr.data = fvalue_get_bytes_data(fi->value);
10440 |
10441 | addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10442 | label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10443 | wmem_free(NULL((void*)0), addr_str);
10444 | break;
10445 |
10446 | case FT_ETHER:
10447 | bytes = fvalue_get_bytes_data(fi->value);
10448 |
10449 | addr.type = AT_ETHER;
10450 | addr.len = 6;
10451 | addr.data = bytes;
10452 |
10453 | addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10454 | label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10455 | wmem_free(NULL((void*)0), addr_str);
10456 | break;
10457 |
10458 | case FT_IPv4:
10459 | ipv4 = fvalue_get_ipv4(fi->value);
10460 | set_address_ipv4(&addr, ipv4);
10461 |
10462 | if (hfinfo->display == BASE_NETMASK) {
10463 | addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10464 | } else {
10465 | addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10466 | }
10467 | label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10468 | wmem_free(NULL((void*)0), addr_str);
10469 | free_address(&addr);
10470 | break;
10471 |
10472 | case FT_IPv6:
10473 | ipv6 = fvalue_get_ipv6(fi->value);
10474 | set_address_ipv6(&addr, ipv6);
10475 |
10476 | addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10477 | label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10478 | wmem_free(NULL((void*)0), addr_str);
10479 | free_address(&addr);
10480 | break;
10481 |
10482 | case FT_FCWWN:
10483 | bytes = fvalue_get_bytes_data(fi->value);
10484 | addr.type = AT_FCWWN;
10485 | addr.len = FCWWN_ADDR_LEN8;
10486 | addr.data = bytes;
10487 |
10488 | addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10489 | label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10490 | wmem_free(NULL((void*)0), addr_str);
10491 | break;
10492 |
10493 | case FT_GUID:
10494 | guid = fvalue_get_guid(fi->value);
10495 | tmp = guid_to_str(NULL((void*)0), guid);
10496 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10497 | wmem_free(NULL((void*)0), tmp);
10498 | break;
10499 |
10500 | case FT_OID:
10501 | bytes = fvalue_get_bytes_data(fi->value);
10502 | name = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10503 | tmp = oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10504 | if (name) {
10505 | label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10506 | wmem_free(NULL((void*)0), name);
10507 | } else {
10508 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10509 | }
10510 | wmem_free(NULL((void*)0), tmp);
10511 | break;
10512 |
10513 | case FT_REL_OID:
10514 | bytes = fvalue_get_bytes_data(fi->value);
10515 | name = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10516 | tmp = rel_oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10517 | if (name) {
10518 | label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10519 | wmem_free(NULL((void*)0), name);
10520 | } else {
10521 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10522 | }
10523 | wmem_free(NULL((void*)0), tmp);
10524 | break;
10525 |
10526 | case FT_SYSTEM_ID:
10527 | bytes = fvalue_get_bytes_data(fi->value);
10528 | tmp = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10529 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10530 | wmem_free(NULL((void*)0), tmp);
10531 | break;
10532 |
10533 | case FT_EUI64:
10534 | bytes = fvalue_get_bytes_data(fi->value);
10535 | addr.type = AT_EUI64;
10536 | addr.len = EUI64_ADDR_LEN8;
10537 | addr.data = bytes;
10538 |
10539 | addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10540 | label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10541 | wmem_free(NULL((void*)0), addr_str);
10542 | break;
10543 | case FT_STRING:
10544 | case FT_STRINGZ:
10545 | case FT_UINT_STRING:
10546 | case FT_STRINGZPAD:
10547 | case FT_STRINGZTRUNC:
10548 | case FT_AX25:
10549 | str = fvalue_get_string(fi->value);
10550 | label_fill(label_str, 0, hfinfo, str, value_pos);
10551 | break;
10552 |
10553 | case FT_IEEE_11073_SFLOAT:
10554 | case FT_IEEE_11073_FLOAT:
10555 | fill_label_ieee_11073_float(fi, label_str, value_pos);
10556 | break;
10557 |
10558 | default:
10559 | 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 ))
10560 | 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 ))
10561 | 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 ))
10562 | 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 ));
10563 | break;
10564 | }
10565 | }
10566 |
10567 | static void
10568 | fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos)
10569 | {
10570 | char *p;
10571 | int bitfield_byte_length = 0, bitwidth;
10572 | uint64_t unshifted_value;
10573 | uint64_t value;
10574 |
10575 | const header_field_info *hfinfo = fi->hfinfo;
10576 |
10577 | value = fvalue_get_uinteger64(fi->value);
10578 | if (hfinfo->bitmask) {
10579 | /* Figure out the bit width */
10580 | bitwidth = hfinfo_container_bitwidth(hfinfo);
10581 |
10582 | /* Un-shift bits */
10583 | unshifted_value = value;
10584 | unshifted_value <<= hfinfo_bitshift(hfinfo);
10585 |
10586 | /* Create the bitfield first */
10587 | p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10588 | bitfield_byte_length = (int) (p - label_str);
10589 | }
10590 |
10591 | /* Fill in the textual info */
10592 | label_fill(label_str, bitfield_byte_length, hfinfo, tfs_get_string(!!value, hfinfo->strings), value_pos);
10593 | }
10594 |
10595 | static const char *
10596 | hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo)
10597 | {
10598 | if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10599 | return try_rval_to_str(value, (const range_string *) hfinfo->strings);
10600 |
10601 | if (hfinfo->display & BASE_EXT_STRING0x00000200) {
10602 | if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10603 | return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10604 | else
10605 | return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
10606 | }
10607 |
10608 | if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10609 | return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10610 |
10611 | if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10612 | return unit_name_string_get_value(value, (const struct unit_name_string*) hfinfo->strings);
10613 |
10614 | return try_val_to_str(value, (const value_string *) hfinfo->strings);
10615 | }
10616 |
10617 | static const char *
10618 | hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo)
10619 | {
10620 | if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
10621 | if (hfinfo->display & BASE_EXT_STRING0x00000200)
10622 | return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10623 | else
10624 | return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10625 | }
10626 |
10627 | if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10628 | return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
10629 |
10630 | if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10631 | return unit_name_string_get_value64(value, (const struct unit_name_string*) hfinfo->strings);
10632 |
10633 | /* If this is reached somebody registered a 64-bit field with a 32-bit
10634 | * value-string, which isn't right. */
10635 | 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)
10636 | hfinfo->abbrev)proto_report_dissector_bug("field %s is a 64-bit field with a 32-bit value_string" , hfinfo->abbrev);
10637 |
10638 | /* This is necessary to squelch MSVC errors; is there
10639 | any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10640 | never returns? */
10641 | return NULL((void*)0);
10642 | }
10643 |
10644 | static const char *
10645 | hf_try_double_val_to_str(double value, const header_field_info *hfinfo)
10646 | {
10647 | if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10648 | return unit_name_string_get_double(value, (const struct unit_name_string*)hfinfo->strings);
10649 |
10650 | 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);
10651 |
10652 | /* This is necessary to squelch MSVC errors; is there
10653 | any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10654 | never returns? */
10655 | return NULL((void*)0);
10656 | }
10657 |
10658 | static const char *
10659 | hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str)
10660 | {
10661 | const char *str = hf_try_val_to_str(value, hfinfo);
10662 |
10663 | return (str) ? str : unknown_str;
10664 | }
10665 |
10666 | static const char *
10667 | hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str)
10668 | {
10669 | const char *str = hf_try_val64_to_str(value, hfinfo);
10670 |
10671 | return (str) ? str : unknown_str;
10672 | }
10673 |
10674 | /* Fills data for bitfield chars with val_strings */
10675 | static void
10676 | fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos)
10677 | {
10678 | char *p;
10679 | int bitfield_byte_length, bitwidth;
10680 | uint32_t unshifted_value;
10681 | uint32_t value;
10682 |
10683 | char buf[32];
10684 | const char *out;
10685 |
10686 | const header_field_info *hfinfo = fi->hfinfo;
10687 |
10688 | /* Figure out the bit width */
10689 | bitwidth = hfinfo_container_bitwidth(hfinfo);
10690 |
10691 | /* Un-shift bits */
10692 | value = fvalue_get_uinteger(fi->value);
10693 |
10694 | unshifted_value = value;
10695 | if (hfinfo->bitmask) {
10696 | unshifted_value <<= hfinfo_bitshift(hfinfo);
10697 | }
10698 |
10699 | /* Create the bitfield first */
10700 | p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10701 | bitfield_byte_length = (int) (p - label_str);
10702 |
10703 | /* Fill in the textual info using stored (shifted) value */
10704 | if (hfinfo->display == BASE_CUSTOM) {
10705 | char tmp[ITEM_LABEL_LENGTH240];
10706 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10707 |
10708 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 10708, "fmtfunc"))));
10709 | fmtfunc(tmp, value);
10710 | label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10711 | }
10712 | else if (hfinfo->strings) {
10713 | const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10714 |
10715 | out = hfinfo_char_vals_format(hfinfo, buf, value);
10716 | if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10717 | label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10718 | else
10719 | label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10720 | }
10721 | else {
10722 | out = hfinfo_char_value_format(hfinfo, buf, value);
10723 |
10724 | label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10725 | }
10726 | }
10727 |
10728 | /* Fills data for bitfield ints with val_strings */
10729 | static void
10730 | fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10731 | {
10732 | char *p;
10733 | int bitfield_byte_length, bitwidth;
10734 | uint32_t value, unshifted_value;
10735 | char buf[NUMBER_LABEL_LENGTH80];
10736 | const char *out;
10737 |
10738 | const header_field_info *hfinfo = fi->hfinfo;
10739 |
10740 | /* Figure out the bit width */
10741 | if (fi->flags & FI_VARINT0x00040000)
10742 | bitwidth = fi->length*8;
10743 | else
10744 | bitwidth = hfinfo_container_bitwidth(hfinfo);
10745 |
10746 | /* Un-shift bits */
10747 | if (is_signed)
10748 | value = fvalue_get_sinteger(fi->value);
10749 | else
10750 | value = fvalue_get_uinteger(fi->value);
10751 |
10752 | unshifted_value = value;
10753 | if (hfinfo->bitmask) {
10754 | unshifted_value <<= hfinfo_bitshift(hfinfo);
10755 | }
10756 |
10757 | /* Create the bitfield first */
10758 | if (fi->flags & FI_VARINT0x00040000)
10759 | p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10760 | else
10761 | p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10762 | bitfield_byte_length = (int) (p - label_str);
10763 |
10764 | /* Fill in the textual info using stored (shifted) value */
10765 | if (hfinfo->display == BASE_CUSTOM) {
10766 | char tmp[ITEM_LABEL_LENGTH240];
10767 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10768 |
10769 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 10769, "fmtfunc"))));
10770 | fmtfunc(tmp, value);
10771 | label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10772 | }
10773 | else if (hfinfo->strings) {
10774 | const char *val_str = hf_try_val_to_str(value, hfinfo);
10775 |
10776 | out = hfinfo_number_vals_format(hfinfo, buf, value);
10777 | if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10778 | /*
10779 | * Unique values only display value_string string
10780 | * if there is a match. Otherwise it's just a number
10781 | */
10782 | if (val_str) {
10783 | label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10784 | } else {
10785 | label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10786 | }
10787 | } else {
10788 | if (val_str == NULL((void*)0))
10789 | val_str = "Unknown";
10790 |
10791 | if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10792 | label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10793 | else
10794 | label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10795 | }
10796 | }
10797 | else {
10798 | out = hfinfo_number_value_format(hfinfo, buf, value);
10799 |
10800 | label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10801 | }
10802 | }
10803 |
10804 | static void
10805 | fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10806 | {
10807 | char *p;
10808 | int bitfield_byte_length, bitwidth;
10809 | uint64_t value, unshifted_value;
10810 | char buf[NUMBER_LABEL_LENGTH80];
10811 | const char *out;
10812 |
10813 | const header_field_info *hfinfo = fi->hfinfo;
10814 |
10815 | /* Figure out the bit width */
10816 | if (fi->flags & FI_VARINT0x00040000)
10817 | bitwidth = fi->length*8;
10818 | else
10819 | bitwidth = hfinfo_container_bitwidth(hfinfo);
10820 |
10821 | /* Un-shift bits */
10822 | if (is_signed)
10823 | value = fvalue_get_sinteger64(fi->value);
10824 | else
10825 | value = fvalue_get_uinteger64(fi->value);
10826 |
10827 | unshifted_value = value;
10828 | if (hfinfo->bitmask) {
10829 | unshifted_value <<= hfinfo_bitshift(hfinfo);
10830 | }
10831 |
10832 | /* Create the bitfield first */
10833 | if (fi->flags & FI_VARINT0x00040000)
10834 | p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10835 | else
10836 | p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10837 | bitfield_byte_length = (int) (p - label_str);
10838 |
10839 | /* Fill in the textual info using stored (shifted) value */
10840 | if (hfinfo->display == BASE_CUSTOM) {
10841 | char tmp[ITEM_LABEL_LENGTH240];
10842 | const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10843 |
10844 | DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug( "%s:%u: failed assertion \"%s\"", "epan/proto.c", 10844, "fmtfunc64" ))));
10845 | fmtfunc64(tmp, value);
10846 | label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10847 | }
10848 | else if (hfinfo->strings) {
10849 | const char *val_str = hf_try_val64_to_str(value, hfinfo);
10850 |
10851 | out = hfinfo_number_vals_format64(hfinfo, buf, value);
10852 | if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10853 | /*
10854 | * Unique values only display value_string string
10855 | * if there is a match. Otherwise it's just a number
10856 | */
10857 | if (val_str) {
10858 | label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10859 | } else {
10860 | label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10861 | }
10862 | } else {
10863 | if (val_str == NULL((void*)0))
10864 | val_str = "Unknown";
10865 |
10866 | if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10867 | label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10868 | else
10869 | label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10870 | }
10871 | }
10872 | else {
10873 | out = hfinfo_number_value_format64(hfinfo, buf, value);
10874 |
10875 | label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10876 | }
10877 | }
10878 |
10879 | static void
10880 | fill_label_char(const field_info *fi, char *label_str, size_t *value_pos)
10881 | {
10882 | const header_field_info *hfinfo = fi->hfinfo;
10883 | uint32_t value;
10884 |
10885 | char buf[32];
10886 | const char *out;
10887 |
10888 | value = fvalue_get_uinteger(fi->value);
10889 |
10890 | /* Fill in the textual info */
10891 | if (hfinfo->display == BASE_CUSTOM) {
10892 | char tmp[ITEM_LABEL_LENGTH240];
10893 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10894 |
10895 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 10895, "fmtfunc"))));
10896 | fmtfunc(tmp, value);
10897 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10898 | }
10899 | else if (hfinfo->strings) {
10900 | const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10901 |
10902 | out = hfinfo_char_vals_format(hfinfo, buf, value);
10903 | label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10904 | }
10905 | else {
10906 | out = hfinfo_char_value_format(hfinfo, buf, value);
10907 |
10908 | label_fill(label_str, 0, hfinfo, out, value_pos);
10909 | }
10910 | }
10911 |
10912 | static void
10913 | fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10914 | {
10915 | const header_field_info *hfinfo = fi->hfinfo;
10916 | uint32_t value;
10917 |
10918 | char buf[NUMBER_LABEL_LENGTH80];
10919 | const char *out;
10920 |
10921 | if (is_signed)
10922 | value = fvalue_get_sinteger(fi->value);
10923 | else
10924 | value = fvalue_get_uinteger(fi->value);
10925 |
10926 | /* Fill in the textual info */
10927 | if (hfinfo->display == BASE_CUSTOM) {
10928 | char tmp[ITEM_LABEL_LENGTH240];
10929 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10930 |
10931 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 10931, "fmtfunc"))));
10932 | fmtfunc(tmp, value);
10933 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10934 | }
10935 | else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
10936 | /*
10937 | * It makes no sense to have a value-string table for a
10938 | * frame-number field - they're just integers giving
10939 | * the ordinal frame number.
10940 | */
10941 | const char *val_str = hf_try_val_to_str(value, hfinfo);
10942 |
10943 | out = hfinfo_number_vals_format(hfinfo, buf, value);
10944 | if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10945 | /*
10946 | * Unique values only display value_string string
10947 | * if there is a match. Otherwise it's just a number
10948 | */
10949 | if (val_str) {
10950 | label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10951 | } else {
10952 | label_fill(label_str, 0, hfinfo, out, value_pos);
10953 | }
10954 | } else {
10955 | if (val_str == NULL((void*)0))
10956 | val_str = "Unknown";
10957 |
10958 | if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10959 | label_fill(label_str, 0, hfinfo, val_str, value_pos);
10960 | else
10961 | label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10962 | }
10963 | }
10964 | 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 ))) {
10965 | char tmp[ITEM_LABEL_LENGTH240];
10966 |
10967 | port_with_resolution_to_str_buf(tmp, sizeof(tmp),
10968 | display_to_port_type((field_display_e)hfinfo->display), value);
10969 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10970 | }
10971 | else {
10972 | out = hfinfo_number_value_format(hfinfo, buf, value);
10973 |
10974 | label_fill(label_str, 0, hfinfo, out, value_pos);
10975 | }
10976 | }
10977 |
10978 | static void
10979 | fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10980 | {
10981 | const header_field_info *hfinfo = fi->hfinfo;
10982 | uint64_t value;
10983 |
10984 | char buf[NUMBER_LABEL_LENGTH80];
10985 | const char *out;
10986 |
10987 | if (is_signed)
10988 | value = fvalue_get_sinteger64(fi->value);
10989 | else
10990 | value = fvalue_get_uinteger64(fi->value);
10991 |
10992 | /* Fill in the textual info */
10993 | if (hfinfo->display == BASE_CUSTOM) {
10994 | char tmp[ITEM_LABEL_LENGTH240];
10995 | const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10996 |
10997 | DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug( "%s:%u: failed assertion \"%s\"", "epan/proto.c", 10997, "fmtfunc64" ))));
10998 | fmtfunc64(tmp, value);
10999 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
11000 | }
11001 | else if (hfinfo->strings) {
11002 | const char *val_str = hf_try_val64_to_str(value, hfinfo);
11003 |
11004 | out = hfinfo_number_vals_format64(hfinfo, buf, value);
11005 | if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
11006 | /*
11007 | * Unique values only display value_string string
11008 | * if there is a match. Otherwise it's just a number
11009 | */
11010 | if (val_str) {
11011 | label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11012 | } else {
11013 | label_fill(label_str, 0, hfinfo, out, value_pos);
11014 | }
11015 | } else {
11016 | if (val_str == NULL((void*)0))
11017 | val_str = "Unknown";
11018 |
11019 | if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
11020 | label_fill(label_str, 0, hfinfo, val_str, value_pos);
11021 | else
11022 | label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11023 | }
11024 | }
11025 | else {
11026 | out = hfinfo_number_value_format64(hfinfo, buf, value);
11027 |
11028 | label_fill(label_str, 0, hfinfo, out, value_pos);
11029 | }
11030 | }
11031 |
11032 | static size_t
11033 | fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size)
11034 | {
11035 | int display;
11036 | int n;
11037 | double value;
11038 |
11039 | if (label_str_size < 12) {
11040 | /* Not enough room to write an entire floating point value. */
11041 | return 0;
11042 | }
11043 |
11044 | display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
11045 | value = fvalue_get_floating(fi->value);
11046 |
11047 | if (display == BASE_CUSTOM) {
11048 | const custom_fmt_func_double_t fmtfunc = (const custom_fmt_func_double_t)fi->hfinfo->strings;
11049 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 11049, "fmtfunc"))));
11050 | fmtfunc(label_str, value);
11051 | return strlen(label_str);
11052 | }
11053 |
11054 | switch (display) {
11055 | case BASE_NONE:
11056 | if (fi->hfinfo->type == FT_FLOAT) {
11057 | n = snprintf(label_str, label_str_size, "%.*g", FLT_DIG6, value);
11058 | } else {
11059 | n = (int)strlen(dtoa_g_fmt(label_str, value));
11060 | }
11061 | break;
11062 | case BASE_DEC:
11063 | n = snprintf(label_str, label_str_size, "%f", value);
11064 | break;
11065 | case BASE_HEX:
11066 | n = snprintf(label_str, label_str_size, "%a", value);
11067 | break;
11068 | case BASE_EXP:
11069 | n = snprintf(label_str, label_str_size, "%e", value);
11070 | break;
11071 | default:
11072 | ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 11072 , __func__, "assertion \"not reached\" failed");
11073 | }
11074 | if (n < 0) {
11075 | return 0; /* error */
11076 | }
11077 | if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
11078 | const char *hf_str_val;
11079 | hf_str_val = hf_try_double_val_to_str(value, fi->hfinfo);
11080 | n += proto_strlcpy(label_str + n, hf_str_val, label_str_size - n);
11081 | }
11082 | if (n > label_str_size) {
11083 | ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 11083, __func__, "label length too small"); } } while (0);
11084 | return strlen(label_str);
11085 | }
11086 |
11087 | return n;
11088 | }
11089 |
11090 | void
11091 | fill_label_float(const field_info *fi, char *label_str, size_t *value_pos)
11092 | {
11093 | char tmp[ITEM_LABEL_LENGTH240];
11094 |
11095 | fill_display_label_float(fi, tmp, ITEM_LABEL_LENGTH240);
11096 | label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
11097 | }
11098 |
11099 | static size_t
11100 | fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size)
11101 | {
11102 | int display;
11103 | size_t pos = 0;
11104 | double value;
11105 | char* tmp_str;
11106 |
11107 | if (label_str_size < 12) {
11108 | /* Not enough room to write an entire floating point value. */
11109 | return 0;
11110 | }
11111 |
11112 | display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
11113 | tmp_str = fvalue_to_string_repr(NULL((void*)0), fi->value, FTREPR_DISPLAY, display);
11114 | pos = label_concat(label_str, pos, (const uint8_t*)tmp_str)ws_label_strcpy(label_str, 240, pos, (const uint8_t*)tmp_str, 0);
11115 | wmem_free(NULL((void*)0), tmp_str);
11116 |
11117 | if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
11118 | const char *hf_str_val;
11119 | fvalue_to_double(fi->value, &value);
11120 | hf_str_val = unit_name_string_get_double(value, (const struct unit_name_string*)fi->hfinfo->strings);
11121 | 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);
11122 | }
11123 | if ((int)pos > label_str_size) {
11124 | ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 11124, __func__, "label length too small"); } } while (0);
11125 | return strlen(label_str);
11126 | }
11127 |
11128 | return pos;
11129 | }
11130 |
11131 | void
11132 | fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos)
11133 | {
11134 | char tmp[ITEM_LABEL_LENGTH240];
11135 |
11136 | fill_display_label_ieee_11073_float(fi, tmp, ITEM_LABEL_LENGTH240);
11137 | label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
11138 | }
11139 |
11140 | int
11141 | hfinfo_bitshift(const header_field_info *hfinfo)
11142 | {
11143 | return ws_ctz(hfinfo->bitmask);
11144 | }
11145 |
11146 |
11147 | static int
11148 | hfinfo_bitoffset(const header_field_info *hfinfo)
11149 | {
11150 | if (!hfinfo->bitmask) {
11151 | return 0;
11152 | }
11153 |
11154 | /* ilog2 = first set bit, counting 0 as the last bit; we want 0
11155 | * as the first bit */
11156 | return hfinfo_container_bitwidth(hfinfo) - 1 - ws_ilog2(hfinfo->bitmask);
11157 | }
11158 |
11159 | static int
11160 | hfinfo_mask_bitwidth(const header_field_info *hfinfo)
11161 | {
11162 | if (!hfinfo->bitmask) {
11163 | return 0;
11164 | }
11165 |
11166 | /* ilog2 = first set bit, ctz = last set bit */
11167 | return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
11168 | }
11169 |
11170 | static int
11171 | hfinfo_type_bitwidth(enum ftenum type)
11172 | {
11173 | int bitwidth = 0;
11174 |
11175 | switch (type) {
11176 | case FT_CHAR:
11177 | case FT_UINT8:
11178 | case FT_INT8:
11179 | bitwidth = 8;
11180 | break;
11181 | case FT_UINT16:
11182 | case FT_INT16:
11183 | bitwidth = 16;
11184 | break;
11185 | case FT_UINT24:
11186 | case FT_INT24:
11187 | bitwidth = 24;
11188 | break;
11189 | case FT_UINT32:
11190 | case FT_INT32:
11191 | bitwidth = 32;
11192 | break;
11193 | case FT_UINT40:
11194 | case FT_INT40:
11195 | bitwidth = 40;
11196 | break;
11197 | case FT_UINT48:
11198 | case FT_INT48:
11199 | bitwidth = 48;
11200 | break;
11201 | case FT_UINT56:
11202 | case FT_INT56:
11203 | bitwidth = 56;
11204 | break;
11205 | case FT_UINT64:
11206 | case FT_INT64:
11207 | bitwidth = 64;
11208 | break;
11209 | default:
11210 | DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\"" , "epan/proto.c", 11210));
11211 | ;
11212 | }
11213 | return bitwidth;
11214 | }
11215 |
11216 |
11217 | static int
11218 | hfinfo_container_bitwidth(const header_field_info *hfinfo)
11219 | {
11220 | if (!hfinfo->bitmask) {
11221 | return 0;
11222 | }
11223 |
11224 | if (hfinfo->type == FT_BOOLEAN) {
11225 | return hfinfo->display; /* hacky? :) */
11226 | }
11227 |
11228 | return hfinfo_type_bitwidth(hfinfo->type);
11229 | }
11230 |
11231 | static int
11232 | hfinfo_hex_digits(const header_field_info *hfinfo)
11233 | {
11234 | int bitwidth;
11235 |
11236 | /* If we have a bitmask, hfinfo->type is the width of the container, so not
11237 | * appropriate to determine the number of hex digits for the field.
11238 | * So instead, we compute it from the bitmask.
11239 | */
11240 | if (hfinfo->bitmask != 0) {
11241 | bitwidth = hfinfo_mask_bitwidth(hfinfo);
11242 | } else {
11243 | bitwidth = hfinfo_type_bitwidth(hfinfo->type);
11244 | }
11245 |
11246 | /* Divide by 4, rounding up, to get number of hex digits. */
11247 | return (bitwidth + 3) / 4;
11248 | }
11249 |
11250 | const char *
11251 | hfinfo_char_value_format_display(int display, char buf[7], uint32_t value)
11252 | {
11253 | char *ptr = &buf[6];
11254 | static const char hex_digits[16] =
11255 | { '0', '1', '2', '3', '4', '5', '6', '7',
11256 | '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
11257 |
11258 | *ptr = '\0';
11259 | *(--ptr) = '\'';
11260 | /* Properly format value */
11261 | if (g_ascii_isprint(value)((g_ascii_table[(guchar) (value)] & G_ASCII_PRINT) != 0)) {
11262 | /*
11263 | * Printable, so just show the character, and, if it needs
11264 | * to be escaped, escape it.
11265 | */
11266 | *(--ptr) = value;
11267 | if (value == '\\' || value == '\'')
11268 | *(--ptr) = '\\';
11269 | } else {
11270 | /*
11271 | * Non-printable; show it as an escape sequence.
11272 | */
11273 | switch (value) {
11274 |
11275 | case '\0':
11276 | /*
11277 | * Show a NUL with only one digit.
11278 | */
11279 | *(--ptr) = '0';
11280 | break;
11281 |
11282 | case '\a':
11283 | case '\b':
11284 | case '\f':
11285 | case '\n':
11286 | case '\r':
11287 | case '\t':
11288 | case '\v':
11289 | *(--ptr) = value - '\a' + 'a';
11290 | break;
11291 |
11292 | default:
11293 | switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11294 |
11295 | case BASE_OCT:
11296 | *(--ptr) = (value & 0x7) + '0';
11297 | value >>= 3;
11298 | *(--ptr) = (value & 0x7) + '0';
11299 | value >>= 3;
11300 | *(--ptr) = (value & 0x7) + '0';
11301 | break;
11302 |
11303 | case BASE_HEX:
11304 | *(--ptr) = hex_digits[value & 0x0F];
11305 | value >>= 4;
11306 | *(--ptr) = hex_digits[value & 0x0F];
11307 | *(--ptr) = 'x';
11308 | break;
11309 |
11310 | default:
11311 | REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) & 0xFF));
11312 | }
11313 | }
11314 | *(--ptr) = '\\';
11315 | }
11316 | *(--ptr) = '\'';
11317 | return ptr;
11318 | }
11319 |
11320 | static const char *
11321 | hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11322 | {
11323 | char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11324 | 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 ));
11325 |
11326 | *ptr = '\0';
11327 | /* Properly format value */
11328 | switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11329 | case BASE_DEC:
11330 | return isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11331 |
11332 | case BASE_DEC_HEX:
11333 | *(--ptr) = ')';
11334 | ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11335 | *(--ptr) = '(';
11336 | *(--ptr) = ' ';
11337 | ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11338 | return ptr;
11339 |
11340 | case BASE_OCT:
11341 | return oct_to_str_back(ptr, value);
11342 |
11343 | case BASE_HEX:
11344 | return hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11345 |
11346 | case BASE_HEX_DEC:
11347 | *(--ptr) = ')';
11348 | ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11349 | *(--ptr) = '(';
11350 | *(--ptr) = ' ';
11351 | ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11352 | return ptr;
11353 |
11354 | case BASE_PT_UDP:
11355 | case BASE_PT_TCP:
11356 | case BASE_PT_DCCP:
11357 | case BASE_PT_SCTP:
11358 | port_with_resolution_to_str_buf(buf, NUMBER_LABEL_LENGTH80,
11359 | display_to_port_type((field_display_e)display), value);
11360 | return buf;
11361 | case BASE_OUI:
11362 | {
11363 | uint8_t p_oui[3];
11364 | const char *manuf_name;
11365 |
11366 | p_oui[0] = value >> 16 & 0xFF;
11367 | p_oui[1] = value >> 8 & 0xFF;
11368 | p_oui[2] = value & 0xFF;
11369 |
11370 | /* Attempt an OUI lookup. */
11371 | manuf_name = uint_get_manuf_name_if_known(value);
11372 | if (manuf_name == NULL((void*)0)) {
11373 | /* Could not find an OUI. */
11374 | snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x", p_oui[0], p_oui[1], p_oui[2]);
11375 | }
11376 | else {
11377 | /* Found an address string. */
11378 | snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x (%s)", p_oui[0], p_oui[1], p_oui[2], manuf_name);
11379 | }
11380 | return buf;
11381 | }
11382 |
11383 | default:
11384 | REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) & 0xFF));
11385 | }
11386 | return ptr;
11387 | }
11388 |
11389 | static const char *
11390 | hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11391 | {
11392 | char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11393 | 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 ));
11394 |
11395 | *ptr = '\0';
11396 | /* Properly format value */
11397 | switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11398 | case BASE_DEC:
11399 | return isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11400 |
11401 | case BASE_DEC_HEX:
11402 | *(--ptr) = ')';
11403 | ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11404 | *(--ptr) = '(';
11405 | *(--ptr) = ' ';
11406 | ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11407 | return ptr;
11408 |
11409 | case BASE_OCT:
11410 | return oct64_to_str_back(ptr, value);
11411 |
11412 | case BASE_HEX:
11413 | return hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11414 |
11415 | case BASE_HEX_DEC:
11416 | *(--ptr) = ')';
11417 | ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11418 | *(--ptr) = '(';
11419 | *(--ptr) = ' ';
11420 | ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11421 | return ptr;
11422 |
11423 | default:
11424 | REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) & 0xFF));
11425 | }
11426 |
11427 | return ptr;
11428 | }
11429 |
11430 | static const char *
11431 | hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11432 | {
11433 | int display = hfinfo->display;
11434 |
11435 | if (hfinfo->type == FT_FRAMENUM) {
11436 | /*
11437 | * Frame numbers are always displayed in decimal.
11438 | */
11439 | display = BASE_DEC;
11440 | }
11441 |
11442 | return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11443 | }
11444 |
11445 | static const char *
11446 | hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11447 | {
11448 | int display = hfinfo->display;
11449 |
11450 | if (hfinfo->type == FT_FRAMENUM) {
11451 | /*
11452 | * Frame numbers are always displayed in decimal.
11453 | */
11454 | display = BASE_DEC;
11455 | }
11456 |
11457 | return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11458 | }
11459 |
11460 | static const char *
11461 | hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11462 | {
11463 | /* Get the underlying BASE_ value */
11464 | int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11465 |
11466 | return hfinfo_char_value_format_display(display, buf, value);
11467 | }
11468 |
11469 | static const char *
11470 | hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11471 | {
11472 | /* Get the underlying BASE_ value */
11473 | int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11474 |
11475 | if (hfinfo->type == FT_FRAMENUM) {
11476 | /*
11477 | * Frame numbers are always displayed in decimal.
11478 | */
11479 | display = BASE_DEC;
11480 | }
11481 |
11482 | if (IS_BASE_PORT(display)(((display)==BASE_PT_UDP||(display)==BASE_PT_TCP||(display)== BASE_PT_DCCP||(display)==BASE_PT_SCTP))) {
11483 | display = BASE_DEC;
11484 | } else if (display == BASE_OUI) {
11485 | display = BASE_HEX;
11486 | }
11487 |
11488 | switch (display) {
11489 | case BASE_NONE:
11490 | /* case BASE_DEC: */
11491 | case BASE_DEC_HEX:
11492 | case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11493 | case BASE_CUSTOM:
11494 | display = BASE_DEC;
11495 | break;
11496 |
11497 | /* case BASE_HEX: */
11498 | case BASE_HEX_DEC:
11499 | display = BASE_HEX;
11500 | break;
11501 | }
11502 |
11503 | return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11504 | }
11505 |
11506 | static const char *
11507 | hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11508 | {
11509 | /* Get the underlying BASE_ value */
11510 | int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11511 |
11512 | if (hfinfo->type == FT_FRAMENUM) {
11513 | /*
11514 | * Frame numbers are always displayed in decimal.
11515 | */
11516 | display = BASE_DEC;
11517 | }
11518 |
11519 | switch (display) {
11520 | case BASE_NONE:
11521 | /* case BASE_DEC: */
11522 | case BASE_DEC_HEX:
11523 | case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11524 | case BASE_CUSTOM:
11525 | display = BASE_DEC;
11526 | break;
11527 |
11528 | /* case BASE_HEX: */
11529 | case BASE_HEX_DEC:
11530 | display = BASE_HEX;
11531 | break;
11532 | }
11533 |
11534 | return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11535 | }
11536 |
11537 | static const char *
11538 | hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11539 | {
11540 | /* Get the underlying BASE_ value */
11541 | int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11542 |
11543 | return hfinfo_char_value_format_display(display, buf, value);
11544 | }
11545 |
11546 | static const char *
11547 | hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11548 | {
11549 | /* Get the underlying BASE_ value */
11550 | int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11551 |
11552 | if (display == BASE_NONE)
11553 | return NULL((void*)0);
11554 |
11555 | if (display == BASE_DEC_HEX)
11556 | display = BASE_DEC;
11557 | if (display == BASE_HEX_DEC)
11558 | display = BASE_HEX;
11559 |
11560 | return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11561 | }
11562 |
11563 | static const char *
11564 | hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11565 | {
11566 | /* Get the underlying BASE_ value */
11567 | int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11568 |
11569 | if (display == BASE_NONE)
11570 | return NULL((void*)0);
11571 |
11572 | if (display == BASE_DEC_HEX)
11573 | display = BASE_DEC;
11574 | if (display == BASE_HEX_DEC)
11575 | display = BASE_HEX;
11576 |
11577 | return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11578 | }
11579 |
11580 | const char *
11581 | proto_registrar_get_name(const int n)
11582 | {
11583 | header_field_info *hfinfo;
11584 |
11585 | 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", 11585 , __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", 11585 , "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", 11585, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[n];;
11586 | return hfinfo->name;
11587 | }
11588 |
11589 | const char *
11590 | proto_registrar_get_abbrev(const int n)
11591 | {
11592 | header_field_info *hfinfo;
11593 |
11594 | 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", 11594 , __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", 11594 , "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", 11594, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[n];;
11595 | return hfinfo->abbrev;
11596 | }
11597 |
11598 | enum ftenum
11599 | proto_registrar_get_ftype(const int n)
11600 | {
11601 | header_field_info *hfinfo;
11602 |
11603 | 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", 11603 , __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", 11603 , "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", 11603, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[n];;
11604 | return hfinfo->type;
11605 | }
11606 |
11607 | int
11608 | proto_registrar_get_parent(const int n)
11609 | {
11610 | header_field_info *hfinfo;
11611 |
11612 | 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", 11612 , __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", 11612 , "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", 11612, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[n];;
11613 | return hfinfo->parent;
11614 | }
11615 |
11616 | bool_Bool
11617 | proto_registrar_is_protocol(const int n)
11618 | {
11619 | header_field_info *hfinfo;
11620 |
11621 | 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", 11621 , __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", 11621 , "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", 11621, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[n];;
11622 | return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? true1 : false0);
11623 | }
11624 |
11625 | /* Returns length of field in packet (not necessarily the length
11626 | * in our internal representation, as in the case of IPv4).
11627 | * 0 means undeterminable at time of registration
11628 | * -1 means the field is not registered. */
11629 | int
11630 | proto_registrar_get_length(const int n)
11631 | {
11632 | header_field_info *hfinfo;
11633 |
11634 | 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", 11634 , __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", 11634 , "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", 11634, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[n];;
11635 | return ftype_wire_size(hfinfo->type);
11636 | }
11637 |
11638 | size_t
11639 | proto_registrar_get_count(struct proto_registrar_stats *stats)
11640 | {
11641 | header_field_info *hfinfo;
11642 |
11643 | // Index zero is not used. We have to skip it.
11644 | size_t total_count = gpa_hfinfo.len - 1;
11645 | if (stats == NULL((void*)0)) {
11646 | return total_count;
11647 | }
11648 | for (uint32_t id = 1; id < gpa_hfinfo.len; id++) {
11649 | if (gpa_hfinfo.hfi[id] == NULL((void*)0)) {
11650 | stats->deregistered_count++;
11651 | continue; /* This is a deregistered protocol or header field */
11652 | }
11653 |
11654 | 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", 11654 , __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", 11654, "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", 11654, "gpa_hfinfo.hfi[id] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[id];;
11655 |
11656 | if (proto_registrar_is_protocol(id))
11657 | stats->protocol_count++;
11658 |
11659 | if (hfinfo->same_name_prev_id != -1)
11660 | stats->same_name_count++;
11661 | }
11662 |
11663 | return total_count;
11664 | }
11665 |
11666 | /* Looks for a protocol or a field in a proto_tree. Returns true if
11667 | * it exists anywhere, or false if it exists nowhere. */
11668 | bool_Bool
11669 | proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
11670 | {
11671 | GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
11672 |
11673 | if (g_ptr_array_len(ptrs)((ptrs) ? (ptrs)->len : 0) > 0) {
11674 | return true1;
11675 | }
11676 | else {
11677 | return false0;
11678 | }
11679 | }
11680 |
11681 | /* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
11682 | * This only works if the hfindex was "primed" before the dissection
11683 | * took place, as we just pass back the already-created GPtrArray*.
11684 | * The caller should *not* free the GPtrArray*; proto_tree_free_node()
11685 | * handles that. */
11686 | GPtrArray *
11687 | proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
11688 | {
11689 | if (!tree)
11690 | return NULL((void*)0);
11691 |
11692 | if (PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids != NULL((void*)0))
11693 | return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids,
11694 | GINT_TO_POINTER(id)((gpointer) (glong) (id)));
11695 | else
11696 | return NULL((void*)0);
11697 | }
11698 |
11699 | bool_Bool
11700 | proto_tracking_interesting_fields(const proto_tree *tree)
11701 | {
11702 | GHashTable *interesting_hfids;
11703 |
11704 | if (!tree)
11705 | return false0;
11706 |
11707 | interesting_hfids = PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids;
11708 |
11709 | return (interesting_hfids != NULL((void*)0)) && g_hash_table_size(interesting_hfids);
11710 | }
11711 |
11712 | /* Helper struct for proto_find_info() and proto_all_finfos() */
11713 | typedef struct {
11714 | GPtrArray *array;
11715 | int id;
11716 | } ffdata_t;
11717 |
11718 | /* Helper function for proto_find_info() */
11719 | static bool_Bool
11720 | find_finfo(proto_node *node, void * data)
11721 | {
11722 | field_info *fi = PNODE_FINFO(node)((node)->finfo);
11723 | if (fi && fi->hfinfo) {
11724 | if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11725 | g_ptr_array_add(((ffdata_t*)data)->array, fi);
11726 | }
11727 | }
11728 |
11729 | /* Don't stop traversing. */
11730 | return false0;
11731 | }
11732 |
11733 | /* Helper function for proto_find_first_info() */
11734 | static bool_Bool
11735 | find_first_finfo(proto_node *node, void *data)
11736 | {
11737 | field_info *fi = PNODE_FINFO(node)((node)->finfo);
11738 | if (fi && fi->hfinfo) {
11739 | if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11740 | g_ptr_array_add(((ffdata_t*)data)->array, fi);
11741 |
11742 | /* Stop traversing. */
11743 | return true1;
11744 | }
11745 | }
11746 |
11747 | /* Continue traversing. */
11748 | return false0;
11749 | }
11750 |
11751 | /* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
11752 | * This works on any proto_tree, primed or unprimed, but actually searches
11753 | * the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11754 | * The caller does need to free the returned GPtrArray with
11755 | * g_ptr_array_free(<array>, true).
11756 | */
11757 | GPtrArray *
11758 | proto_find_finfo(proto_tree *tree, const int id)
11759 | {
11760 | ffdata_t ffdata;
11761 |
11762 | ffdata.array = g_ptr_array_new();
11763 | ffdata.id = id;
11764 |
11765 | proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
11766 |
11767 | return ffdata.array;
11768 | }
11769 |
11770 | /* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
11771 | * This works on any proto_tree, primed or unprimed, but actually searches
11772 | * the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11773 | * The caller does need to free the returned GPtrArray with
11774 | * g_ptr_array_free(<array>, true).
11775 | */
11776 | GPtrArray *
11777 | proto_find_first_finfo(proto_tree *tree, const int id)
11778 | {
11779 | ffdata_t ffdata;
11780 |
11781 | ffdata.array = g_ptr_array_new();
11782 | ffdata.id = id;
11783 |
11784 | proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
11785 |
11786 | return ffdata.array;
11787 | }
11788 |
11789 | /* Helper function for proto_all_finfos() */
11790 | static bool_Bool
11791 | every_finfo(proto_node *node, void * data)
11792 | {
11793 | field_info *fi = PNODE_FINFO(node)((node)->finfo);
11794 | if (fi && fi->hfinfo) {
11795 | g_ptr_array_add(((ffdata_t*)data)->array, fi);
11796 | }
11797 |
11798 | /* Don't stop traversing. */
11799 | return false0;
11800 | }
11801 |
11802 | /* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree.
11803 | * The caller does need to free the returned GPtrArray with
11804 | * g_ptr_array_free(<array>, true).
11805 | */
11806 | GPtrArray *
11807 | proto_all_finfos(proto_tree *tree)
11808 | {
11809 | ffdata_t ffdata;
11810 |
11811 | /* Pre allocate enough space to hold all fields in most cases */
11812 | ffdata.array = g_ptr_array_sized_new(512);
11813 | ffdata.id = 0;
11814 |
11815 | proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
11816 |
11817 | return ffdata.array;
11818 | }
11819 |
11820 |
11821 | typedef struct {
11822 | unsigned offset;
11823 | field_info *finfo;
11824 | tvbuff_t *tvb;
11825 | } offset_search_t;
11826 |
11827 | static bool_Bool
11828 | check_for_offset(proto_node *node, void * data)
11829 | {
11830 | field_info *fi = PNODE_FINFO(node)((node)->finfo);
11831 | offset_search_t *offsearch = (offset_search_t *)data;
11832 |
11833 | /* !fi == the top most container node which holds nothing */
11834 | if (fi && !proto_item_is_hidden(node) && !proto_item_is_generated(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
11835 | if (offsearch->offset >= (unsigned) fi->start &&
11836 | offsearch->offset < (unsigned) (fi->start + fi->length)) {
11837 |
11838 | offsearch->finfo = fi;
11839 | return false0; /* keep traversing */
11840 | }
11841 | }
11842 | return false0; /* keep traversing */
11843 | }
11844 |
11845 | /* Search a proto_tree backwards (from leaves to root) looking for the field
11846 | * whose start/length occupies 'offset' */
11847 | /* XXX - I couldn't find an easy way to search backwards, so I search
11848 | * forwards, w/o stopping. Therefore, the last finfo I find will the be
11849 | * the one I want to return to the user. This algorithm is inefficient
11850 | * and could be re-done, but I'd have to handle all the children and
11851 | * siblings of each node myself. When I have more time I'll do that.
11852 | * (yeah right) */
11853 | field_info *
11854 | proto_find_field_from_offset(proto_tree *tree, unsigned offset, tvbuff_t *tvb)
11855 | {
11856 | offset_search_t offsearch;
11857 |
11858 | offsearch.offset = offset;
11859 | offsearch.finfo = NULL((void*)0);
11860 | offsearch.tvb = tvb;
11861 |
11862 | proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
11863 |
11864 | return offsearch.finfo;
11865 | }
11866 |
11867 | typedef struct {
11868 | unsigned length;
11869 | char *buf;
11870 | } decoded_data_t;
11871 |
11872 | static bool_Bool
11873 | check_for_undecoded(proto_node *node, void * data)
11874 | {
11875 | field_info *fi = PNODE_FINFO(node)((node)->finfo);
11876 | decoded_data_t* decoded = (decoded_data_t*)data;
11877 | unsigned i;
11878 | unsigned byte;
11879 | unsigned bit;
11880 |
11881 | if (fi && fi->hfinfo->type != FT_PROTOCOL) {
11882 | for (i = fi->start; i < fi->start + fi->length && i < decoded->length; i++) {
11883 | byte = i / 8;
11884 | bit = i % 8;
11885 | decoded->buf[byte] |= (1 << bit);
11886 | }
11887 | }
11888 |
11889 | return false0;
11890 | }
11891 |
11892 | char*
11893 | proto_find_undecoded_data(proto_tree *tree, unsigned length)
11894 | {
11895 | decoded_data_t decoded;
11896 | decoded.length = length;
11897 | decoded.buf = (char*)wmem_alloc0(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), length / 8 + 1);
11898 |
11899 | proto_tree_traverse_pre_order(tree, check_for_undecoded, &decoded);
11900 | return decoded.buf;
11901 | }
11902 |
11903 | /* Dumps the protocols in the registration database to stdout. An independent
11904 | * program can take this output and format it into nice tables or HTML or
11905 | * whatever.
11906 | *
11907 | * There is one record per line. The fields are tab-delimited.
11908 | *
11909 | * Field 1 = protocol name
11910 | * Field 2 = protocol short name
11911 | * Field 3 = protocol filter name
11912 | * Field 4 = protocol enabled
11913 | * Field 5 = protocol enabled by default
11914 | * Field 6 = protocol can toggle
11915 | */
11916 | void
11917 | proto_registrar_dump_protocols(void)
11918 | {
11919 | protocol_t *protocol;
11920 | int i;
11921 | void *cookie = NULL((void*)0);
11922 |
11923 |
11924 | i = proto_get_first_protocol(&cookie);
11925 | while (i != -1) {
11926 | protocol = find_protocol_by_id(i);
11927 | printf("%s\t%s\t%s\t%c\t%c\t%c\n",
11928 | protocol->name,
11929 | protocol->short_name,
11930 | protocol->filter_name,
11931 | (proto_is_protocol_enabled_by_default(protocol) ? 'T' : 'F'),
11932 | (proto_is_protocol_enabled(protocol) ? 'T' : 'F'),
11933 | (proto_can_toggle_protocol(protocol->proto_id) ? 'T' : 'F'));
11934 | i = proto_get_next_protocol(&cookie);
11935 | }
11936 | }
11937 |
11938 | /* Dumps the value_strings, extended value string headers, range_strings
11939 | * or true/false strings for fields that have them.
11940 | * There is one record per line. Fields are tab-delimited.
11941 | * There are four types of records: Value String, Extended Value String Header,
11942 | * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
11943 | * the type of record.
11944 | *
11945 | * Note that a record will be generated only if the value_string,... is referenced
11946 | * in a registered hfinfo entry.
11947 | *
11948 | *
11949 | * Value Strings
11950 | * -------------
11951 | * Field 1 = 'V'
11952 | * Field 2 = Field abbreviation to which this value string corresponds
11953 | * Field 3 = Integer value
11954 | * Field 4 = String
11955 | *
11956 | * Extended Value String Headers
11957 | * -----------------------------
11958 | * Field 1 = 'E'
11959 | * Field 2 = Field abbreviation to which this extended value string header corresponds
11960 | * Field 3 = Extended Value String "Name"
11961 | * Field 4 = Number of entries in the associated value_string array
11962 | * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
11963 | *
11964 | * Range Strings
11965 | * -------------
11966 | * Field 1 = 'R'
11967 | * Field 2 = Field abbreviation to which this range string corresponds
11968 | * Field 3 = Integer value: lower bound
11969 | * Field 4 = Integer value: upper bound
11970 | * Field 5 = String
11971 | *
11972 | * True/False Strings
11973 | * ------------------
11974 | * Field 1 = 'T'
11975 | * Field 2 = Field abbreviation to which this true/false string corresponds
11976 | * Field 3 = True String
11977 | * Field 4 = False String
11978 | */
11979 | void
11980 | proto_registrar_dump_values(void)
11981 | {
11982 | header_field_info *hfinfo;
11983 | int i, len, vi;
11984 | const value_string *vals;
11985 | const val64_string *vals64;
11986 | const range_string *range;
11987 | const true_false_string *tfs;
11988 | const unit_name_string *units;
11989 |
11990 | len = gpa_hfinfo.len;
11991 | for (i = 1; i < len ; i++) {
11992 | if (gpa_hfinfo.hfi[i] == NULL((void*)0))
11993 | continue; /* This is a deregistered protocol or field */
11994 |
11995 | 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", 11995 , __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", 11995 , "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", 11995, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[i];;
11996 |
11997 | if (hfinfo->id == hf_text_only) {
11998 | continue;
11999 | }
12000 |
12001 | /* ignore protocols */
12002 | if (proto_registrar_is_protocol(i)) {
12003 | continue;
12004 | }
12005 | /* process header fields */
12006 | #if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
12007 | /*
12008 | * If this field isn't at the head of the list of
12009 | * fields with this name, skip this field - all
12010 | * fields with the same name are really just versions
12011 | * of the same field stored in different bits, and
12012 | * should have the same type/radix/value list, and
12013 | * just differ in their bit masks. (If a field isn't
12014 | * a bitfield, but can be, say, 1 or 2 bytes long,
12015 | * it can just be made FT_UINT16, meaning the
12016 | * *maximum* length is 2 bytes, and be used
12017 | * for all lengths.)
12018 | */
12019 | if (hfinfo->same_name_prev_id != -1)
12020 | continue;
12021 | #endif
12022 | vals = NULL((void*)0);
12023 | vals64 = NULL((void*)0);
12024 | range = NULL((void*)0);
12025 | tfs = NULL((void*)0);
12026 | units = NULL((void*)0);
12027 |
12028 | if (hfinfo->strings != NULL((void*)0)) {
12029 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM &&
12030 | (hfinfo->type == FT_CHAR ||
12031 | hfinfo->type == FT_UINT8 ||
12032 | hfinfo->type == FT_UINT16 ||
12033 | hfinfo->type == FT_UINT24 ||
12034 | hfinfo->type == FT_UINT32 ||
12035 | hfinfo->type == FT_UINT40 ||
12036 | hfinfo->type == FT_UINT48 ||
12037 | hfinfo->type == FT_UINT56 ||
12038 | hfinfo->type == FT_UINT64 ||
12039 | hfinfo->type == FT_INT8 ||
12040 | hfinfo->type == FT_INT16 ||
12041 | hfinfo->type == FT_INT24 ||
12042 | hfinfo->type == FT_INT32 ||
12043 | hfinfo->type == FT_INT40 ||
12044 | hfinfo->type == FT_INT48 ||
12045 | hfinfo->type == FT_INT56 ||
12046 | hfinfo->type == FT_INT64 ||
12047 | hfinfo->type == FT_FLOAT ||
12048 | hfinfo->type == FT_DOUBLE)) {
12049 |
12050 | if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
12051 | range = (const range_string *)hfinfo->strings;
12052 | } else if (hfinfo->display & BASE_EXT_STRING0x00000200) {
12053 | if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12054 | vals64 = VAL64_STRING_EXT_VS_P((const val64_string_ext *)hfinfo->strings)((const val64_string_ext *)hfinfo->strings)->_vs_p;
12055 | } else {
12056 | vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings)((const value_string_ext *)hfinfo->strings)->_vs_p;
12057 | }
12058 | } else if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12059 | vals64 = (const val64_string *)hfinfo->strings;
12060 | } else if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
12061 | units = (const unit_name_string *)hfinfo->strings;
12062 | } else {
12063 | vals = (const value_string *)hfinfo->strings;
12064 | }
12065 | }
12066 | else if (hfinfo->type == FT_BOOLEAN) {
12067 | tfs = (const struct true_false_string *)hfinfo->strings;
12068 | }
12069 | }
12070 |
12071 | /* Print value strings? */
12072 | if (vals) {
12073 | if (hfinfo->display & BASE_EXT_STRING0x00000200) {
12074 | if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12075 | val64_string_ext *vse_p = (val64_string_ext *)hfinfo->strings;
12076 | if (!val64_string_ext_validate(vse_p)) {
12077 | ws_warning("Invalid val64_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 12077, __func__, "Invalid val64_string_ext ptr for: %s", hfinfo ->abbrev); } } while (0);
12078 | continue;
12079 | }
12080 | try_val64_to_str_ext(0, vse_p); /* "prime" the extended val64_string */
12081 | printf("E\t%s\t%u\t%s\t%s\n",
12082 | hfinfo->abbrev,
12083 | VAL64_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
12084 | VAL64_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
12085 | val64_string_ext_match_type_str(vse_p));
12086 | } else {
12087 | value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
12088 | if (!value_string_ext_validate(vse_p)) {
12089 | ws_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 12089, __func__, "Invalid value_string_ext ptr for: %s", hfinfo ->abbrev); } } while (0);
12090 | continue;
12091 | }
12092 | try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
12093 | printf("E\t%s\t%u\t%s\t%s\n",
12094 | hfinfo->abbrev,
12095 | VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
12096 | VALUE_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
12097 | value_string_ext_match_type_str(vse_p));
12098 | }
12099 | }
12100 | vi = 0;
12101 | while (vals[vi].strptr) {
12102 | /* Print in the proper base */
12103 | if (hfinfo->type == FT_CHAR) {
12104 | if (g_ascii_isprint(vals[vi].value)((g_ascii_table[(guchar) (vals[vi].value)] & G_ASCII_PRINT ) != 0)) {
12105 | printf("V\t%s\t'%c'\t%s\n",
12106 | hfinfo->abbrev,
12107 | vals[vi].value,
12108 | vals[vi].strptr);
12109 | } else {
12110 | if (hfinfo->display == BASE_HEX) {
12111 | printf("V\t%s\t'\\x%02x'\t%s\n",
12112 | hfinfo->abbrev,
12113 | vals[vi].value,
12114 | vals[vi].strptr);
12115 | }
12116 | else {
12117 | printf("V\t%s\t'\\%03o'\t%s\n",
12118 | hfinfo->abbrev,
12119 | vals[vi].value,
12120 | vals[vi].strptr);
12121 | }
12122 | }
12123 | } else {
12124 | if (hfinfo->display == BASE_HEX) {
12125 | printf("V\t%s\t0x%x\t%s\n",
12126 | hfinfo->abbrev,
12127 | vals[vi].value,
12128 | vals[vi].strptr);
12129 | }
12130 | else {
12131 | printf("V\t%s\t%u\t%s\n",
12132 | hfinfo->abbrev,
12133 | vals[vi].value,
12134 | vals[vi].strptr);
12135 | }
12136 | }
12137 | vi++;
12138 | }
12139 | }
12140 | else if (vals64) {
12141 | vi = 0;
12142 | while (vals64[vi].strptr) {
12143 | printf("V64\t%s\t%" PRIu64"l" "u" "\t%s\n",
12144 | hfinfo->abbrev,
12145 | vals64[vi].value,
12146 | vals64[vi].strptr);
12147 | vi++;
12148 | }
12149 | }
12150 |
12151 | /* print range strings? */
12152 | else if (range) {
12153 | vi = 0;
12154 | while (range[vi].strptr) {
12155 | /* Print in the proper base */
12156 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_HEX) {
12157 | printf("R\t%s\t0x%"PRIx64"l" "x""\t0x%"PRIx64"l" "x""\t%s\n",
12158 | hfinfo->abbrev,
12159 | range[vi].value_min,
12160 | range[vi].value_max,
12161 | range[vi].strptr);
12162 | }
12163 | else {
12164 | printf("R\t%s\t%"PRIu64"l" "u""\t%"PRIu64"l" "u""\t%s\n",
12165 | hfinfo->abbrev,
12166 | range[vi].value_min,
12167 | range[vi].value_max,
12168 | range[vi].strptr);
12169 | }
12170 | vi++;
12171 | }
12172 | }
12173 |
12174 | /* Print true/false strings? */
12175 | else if (tfs) {
12176 | printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
12177 | tfs->true_string, tfs->false_string);
12178 | }
12179 | /* Print unit strings? */
12180 | else if (units) {
12181 | printf("U\t%s\t%s\t%s\n", hfinfo->abbrev,
12182 | units->singular, units->plural ? units->plural : "(no plural)");
12183 | }
12184 | }
12185 | }
12186 |
12187 | /* Prints the number of registered fields.
12188 | * Useful for determining an appropriate value for
12189 | * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
12190 | *
12191 | * Returns false if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
12192 | * the number of fields, true otherwise.
12193 | */
12194 | bool_Bool
12195 | proto_registrar_dump_fieldcount(void)
12196 | {
12197 | struct proto_registrar_stats stats = {0, 0, 0};
12198 | size_t total_count = proto_registrar_get_count(&stats);
12199 |
12200 | printf("There are %zu header fields registered, of which:\n"
12201 | "\t%zu are deregistered\n"
12202 | "\t%zu are protocols\n"
12203 | "\t%zu have the same name as another field\n\n",
12204 | total_count, stats.deregistered_count, stats.protocol_count,
12205 | stats.same_name_count);
12206 |
12207 | printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000),
12208 | (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000)) ?
12209 | "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
12210 | "\n");
12211 |
12212 | printf("The header field table consumes %u KiB of memory.\n",
12213 | (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
12214 | printf("The fields themselves consume %u KiB of memory.\n",
12215 | (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
12216 |
12217 | return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
12218 | }
12219 |
12220 | static void
12221 | elastic_add_base_mapping(json_dumper *dumper)
12222 | {
12223 | json_dumper_set_member_name(dumper, "index_patterns");
12224 | json_dumper_begin_array(dumper);
12225 | // The index names from write_json_index() in print.c
12226 | json_dumper_value_string(dumper, "packets-*");
12227 | json_dumper_end_array(dumper);
12228 |
12229 | json_dumper_set_member_name(dumper, "settings");
12230 | json_dumper_begin_object(dumper);
12231 | json_dumper_set_member_name(dumper, "index.mapping.total_fields.limit");
12232 | json_dumper_value_anyf(dumper, "%d", 1000000);
12233 | json_dumper_end_object(dumper);
12234 | }
12235 |
12236 | static char*
12237 | ws_type_to_elastic(unsigned type)
12238 | {
12239 | switch(type) {
12240 | case FT_INT8:
12241 | return "byte";
12242 | case FT_UINT8:
12243 | case FT_INT16:
12244 | return "short";
12245 | case FT_UINT16:
12246 | case FT_INT32:
12247 | case FT_UINT24:
12248 | case FT_INT24:
12249 | return "integer";
12250 | case FT_FRAMENUM:
12251 | case FT_UINT32:
12252 | case FT_UINT40:
12253 | case FT_UINT48:
12254 | case FT_UINT56:
12255 | case FT_INT40:
12256 | case FT_INT48:
12257 | case FT_INT56:
12258 | case FT_INT64:
12259 | return "long";
12260 | case FT_UINT64:
12261 | return "unsigned long"; // ElasticSearch since 7.0, OpenSearch 2.8
12262 | case FT_FLOAT:
12263 | return "float";
12264 | case FT_DOUBLE:
12265 | case FT_RELATIVE_TIME: // "scaled_float" with "scaling_factor" 1e9 superior?
12266 | return "double";
12267 | case FT_IPv6:
12268 | case FT_IPv4:
12269 | return "ip";
12270 | case FT_ABSOLUTE_TIME:
12271 | return "date_nanos"; // This is a 64 bit integer of nanoseconds, so it does have a Y2262 problem
12272 | case FT_BOOLEAN:
12273 | return "boolean";
12274 | default:
12275 | return NULL((void*)0);
12276 | }
12277 | }
12278 |
12279 | static char*
12280 | dot_to_underscore(char* str)
12281 | {
12282 | unsigned i;
12283 | for (i = 0; i < strlen(str); i++) {
12284 | if (str[i] == '.')
12285 | str[i] = '_';
12286 | }
12287 | return str;
12288 | }
12289 |
12290 | /* Dumps a mapping file for ElasticSearch
12291 | * This is the v1 (legacy) _template API.
12292 | * At some point it may need to be updated with the composable templates
12293 | * introduced in Elasticsearch 7.8 (_index_template)
12294 | */
12295 | void
12296 | proto_registrar_dump_elastic(const char* filter)
12297 | {
12298 | header_field_info *hfinfo;
12299 | header_field_info *parent_hfinfo;
12300 | unsigned i;
12301 | bool_Bool open_object = true1;
12302 | const char* prev_proto = NULL((void*)0);
12303 | char* str;
12304 | char** protos = NULL((void*)0);
12305 | char* proto;
12306 | bool_Bool found;
12307 | unsigned j;
12308 | char* type;
12309 | char* prev_item = NULL((void*)0);
12310 |
12311 | /* We have filtering protocols. Extract them. */
12312 | if (filter) {
12313 | protos = g_strsplit(filter, ",", -1);
12314 | }
12315 |
12316 | /*
12317 | * To help tracking down the json tree, objects have been appended with a comment:
12318 | * n.label -> where n is the indentation level and label the name of the object
12319 | */
12320 |
12321 | json_dumper dumper = {
12322 | .output_file = stdoutstdout,
12323 | .flags = JSON_DUMPER_FLAGS_PRETTY_PRINT(1 << 0),
12324 | };
12325 | json_dumper_begin_object(&dumper); // 1.root
12326 | elastic_add_base_mapping(&dumper);
12327 |
12328 | json_dumper_set_member_name(&dumper, "mappings");
12329 | json_dumper_begin_object(&dumper); // 2.mappings
12330 |
12331 | json_dumper_set_member_name(&dumper, "properties");
12332 | json_dumper_begin_object(&dumper); // 3.properties
12333 | json_dumper_set_member_name(&dumper, "timestamp");
12334 | json_dumper_begin_object(&dumper); // 4.timestamp
12335 | json_dumper_set_member_name(&dumper, "type");
12336 | json_dumper_value_string(&dumper, "date");
12337 | json_dumper_end_object(&dumper); // 4.timestamp
12338 |
12339 | json_dumper_set_member_name(&dumper, "layers");
12340 | json_dumper_begin_object(&dumper); // 4.layers
12341 | json_dumper_set_member_name(&dumper, "properties");
12342 | json_dumper_begin_object(&dumper); // 5.properties
12343 |
12344 | for (i = 1; i < gpa_hfinfo.len; i++) {
12345 | if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12346 | continue; /* This is a deregistered protocol or header field */
12347 |
12348 | 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", 12348 , __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", 12348 , "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", 12348, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[i];;
12349 |
12350 | /*
12351 | * Skip the pseudo-field for "proto_tree_add_text()" since
12352 | * we don't want it in the list of filterable protocols.
12353 | */
12354 | if (hfinfo->id == hf_text_only)
12355 | continue;
12356 |
12357 | if (!proto_registrar_is_protocol(i)) {
12358 | 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", 12358 , __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", 12358 , "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", 12358 , "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!" )))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];;
12359 |
12360 | /*
12361 | * Skip the field if filter protocols have been set and this one's
12362 | * parent is not listed.
12363 | */
12364 | if (protos) {
12365 | found = false0;
12366 | j = 0;
12367 | proto = protos[0];
12368 | while(proto) {
12369 | if (!g_strcmp0(proto, parent_hfinfo->abbrev)) {
12370 | found = true1;
12371 | break;
12372 | }
12373 | j++;
12374 | proto = protos[j];
12375 | }
12376 | if (!found)
12377 | continue;
12378 | }
12379 |
12380 | if (prev_proto && g_strcmp0(parent_hfinfo->abbrev, prev_proto)) {
12381 | json_dumper_end_object(&dumper); // 7.properties
12382 | json_dumper_end_object(&dumper); // 8.parent_hfinfo->abbrev
12383 | open_object = true1;
12384 | }
12385 |
12386 | prev_proto = parent_hfinfo->abbrev;
12387 |
12388 | if (open_object) {
12389 | json_dumper_set_member_name(&dumper, parent_hfinfo->abbrev);
12390 | json_dumper_begin_object(&dumper); // 6.parent_hfinfo->abbrev
12391 | json_dumper_set_member_name(&dumper, "properties");
12392 | json_dumper_begin_object(&dumper); // 7.properties
12393 | open_object = false0;
12394 | }
12395 | /* Skip the fields that would map into string. This is the default in elasticsearch. */
12396 | type = ws_type_to_elastic(hfinfo->type);
12397 | /* when type is NULL, we have the default mapping: string */
12398 | if (type) {
12399 | str = ws_strdup_printf("%s_%s", prev_proto, hfinfo->abbrev)wmem_strdup_printf(((void*)0), "%s_%s", prev_proto, hfinfo-> abbrev);
12400 | dot_to_underscore(str);
12401 | if (g_strcmp0(prev_item, str)) {
12402 | json_dumper_set_member_name(&dumper, str);
12403 | json_dumper_begin_object(&dumper); // 8.hfinfo->abbrev
12404 | json_dumper_set_member_name(&dumper, "type");
12405 | json_dumper_value_string(&dumper, type);
12406 | json_dumper_end_object(&dumper); // 8.hfinfo->abbrev
12407 | }
12408 | g_free(prev_item)(__builtin_object_size ((prev_item), 0) != ((size_t) - 1)) ? g_free_sized (prev_item, __builtin_object_size ((prev_item), 0)) : (g_free ) (prev_item);
12409 | prev_item = str;
12410 | }
12411 | }
12412 | }
12413 | g_free(prev_item)(__builtin_object_size ((prev_item), 0) != ((size_t) - 1)) ? g_free_sized (prev_item, __builtin_object_size ((prev_item), 0)) : (g_free ) (prev_item);
12414 |
12415 | if (prev_proto) {
12416 | json_dumper_end_object(&dumper); // 7.properties
12417 | json_dumper_end_object(&dumper); // 6.parent_hfinfo->abbrev
12418 | }
12419 |
12420 | json_dumper_end_object(&dumper); // 5.properties
12421 | json_dumper_end_object(&dumper); // 4.layers
12422 | json_dumper_end_object(&dumper); // 3.properties
12423 | json_dumper_end_object(&dumper); // 2.mappings
12424 | json_dumper_end_object(&dumper); // 1.root
12425 | bool_Bool ret = json_dumper_finish(&dumper);
12426 | DISSECTOR_ASSERT(ret)((void) ((ret) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 12426, "ret"))));
12427 |
12428 | g_strfreev(protos);
12429 | }
12430 |
12431 | /* Dumps the contents of the registration database to stdout. An independent
12432 | * program can take this output and format it into nice tables or HTML or
12433 | * whatever.
12434 | *
12435 | * There is one record per line. Each record is either a protocol or a header
12436 | * field, differentiated by the first field. The fields are tab-delimited.
12437 | *
12438 | * Protocols
12439 | * ---------
12440 | * Field 1 = 'P'
12441 | * Field 2 = descriptive protocol name
12442 | * Field 3 = protocol abbreviation
12443 | *
12444 | * Header Fields
12445 | * -------------
12446 | * Field 1 = 'F'
12447 | * Field 2 = descriptive field name
12448 | * Field 3 = field abbreviation
12449 | * Field 4 = type ( textual representation of the ftenum type )
12450 | * Field 5 = parent protocol abbreviation
12451 | * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
12452 | * Field 7 = bitmask: format: hex: 0x....
12453 | * Field 8 = blurb describing field
12454 | */
12455 | void
12456 | proto_registrar_dump_fields(void)
12457 | {
12458 | header_field_info *hfinfo, *parent_hfinfo;
12459 | int i, len;
12460 | const char *enum_name;
12461 | const char *base_name;
12462 | const char *blurb;
12463 | char width[5];
12464 |
12465 | len = gpa_hfinfo.len;
12466 | for (i = 1; i < len ; i++) {
12467 | if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12468 | continue; /* This is a deregistered protocol or header field */
12469 |
12470 | 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", 12470 , __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", 12470 , "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", 12470, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[i];;
12471 |
12472 | /*
12473 | * Skip the pseudo-field for "proto_tree_add_text()" since
12474 | * we don't want it in the list of filterable fields.
12475 | */
12476 | if (hfinfo->id == hf_text_only)
12477 | continue;
12478 |
12479 | /* format for protocols */
12480 | if (proto_registrar_is_protocol(i)) {
12481 | printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
12482 | }
12483 | /* format for header fields */
12484 | else {
12485 | /*
12486 | * If this field isn't at the head of the list of
12487 | * fields with this name, skip this field - all
12488 | * fields with the same name are really just versions
12489 | * of the same field stored in different bits, and
12490 | * should have the same type/radix/value list, and
12491 | * just differ in their bit masks. (If a field isn't
12492 | * a bitfield, but can be, say, 1 or 2 bytes long,
12493 | * it can just be made FT_UINT16, meaning the
12494 | * *maximum* length is 2 bytes, and be used
12495 | * for all lengths.)
12496 | */
12497 | if (hfinfo->same_name_prev_id != -1)
12498 | continue;
12499 |
12500 | 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", 12500 , __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", 12500 , "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", 12500 , "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!" )))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];;
12501 |
12502 | enum_name = ftype_name(hfinfo->type);
12503 | base_name = "";
12504 |
12505 | if (hfinfo->type == FT_CHAR ||
12506 | hfinfo->type == FT_UINT8 ||
12507 | hfinfo->type == FT_UINT16 ||
12508 | hfinfo->type == FT_UINT24 ||
12509 | hfinfo->type == FT_UINT32 ||
12510 | hfinfo->type == FT_UINT40 ||
12511 | hfinfo->type == FT_UINT48 ||
12512 | hfinfo->type == FT_UINT56 ||
12513 | hfinfo->type == FT_UINT64 ||
12514 | hfinfo->type == FT_INT8 ||
12515 | hfinfo->type == FT_INT16 ||
12516 | hfinfo->type == FT_INT24 ||
12517 | hfinfo->type == FT_INT32 ||
12518 | hfinfo->type == FT_INT40 ||
12519 | hfinfo->type == FT_INT48 ||
12520 | hfinfo->type == FT_INT56 ||
12521 | hfinfo->type == FT_INT64) {
12522 |
12523 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
12524 | case BASE_NONE:
12525 | case BASE_DEC:
12526 | case BASE_HEX:
12527 | case BASE_OCT:
12528 | case BASE_DEC_HEX:
12529 | case BASE_HEX_DEC:
12530 | case BASE_CUSTOM:
12531 | case BASE_PT_UDP:
12532 | case BASE_PT_TCP:
12533 | case BASE_PT_DCCP:
12534 | case BASE_PT_SCTP:
12535 | case BASE_OUI:
12536 | base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF), hf_display, "????");
12537 | break;
12538 | default:
12539 | base_name = "????";
12540 | break;
12541 | }
12542 | } else if (hfinfo->type == FT_BOOLEAN) {
12543 | /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
12544 | snprintf(width, sizeof(width), "%d", hfinfo->display);
12545 | base_name = width;
12546 | }
12547 |
12548 | blurb = hfinfo->blurb;
12549 | if (blurb == NULL((void*)0))
12550 | blurb = "";
12551 | else if (strlen(blurb) == 0)
12552 | blurb = "\"\"";
12553 |
12554 | printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" PRIx64"l" "x" "\t%s\n",
12555 | hfinfo->name, hfinfo->abbrev, enum_name,
12556 | parent_hfinfo->abbrev, base_name,
12557 | hfinfo->bitmask, blurb);
12558 | }
12559 | }
12560 | }
12561 |
12562 | /* Dumps all abbreviated field and protocol completions of the given string to
12563 | * stdout. An independent program may use this for command-line tab completion
12564 | * of fields.
12565 | */
12566 | bool_Bool
12567 | proto_registrar_dump_field_completions(const char *prefix)
12568 | {
12569 | header_field_info *hfinfo;
12570 | int i, len;
12571 | size_t prefix_len;
12572 | bool_Bool matched = false0;
12573 |
12574 | prefix_len = strlen(prefix);
12575 | len = gpa_hfinfo.len;
12576 | for (i = 1; i < len ; i++) {
12577 | if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12578 | continue; /* This is a deregistered protocol or header field */
12579 |
12580 | 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", 12580 , __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", 12580 , "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", 12580, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[i];;
12581 |
12582 | /*
12583 | * Skip the pseudo-field for "proto_tree_add_text()" since
12584 | * we don't want it in the list of filterable fields.
12585 | */
12586 | if (hfinfo->id == hf_text_only)
12587 | continue;
12588 |
12589 | /* format for protocols */
12590 | if (proto_registrar_is_protocol(i)) {
12591 | if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12592 | matched = true1;
12593 | printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12594 | }
12595 | }
12596 | /* format for header fields */
12597 | else {
12598 | /*
12599 | * If this field isn't at the head of the list of
12600 | * fields with this name, skip this field - all
12601 | * fields with the same name are really just versions
12602 | * of the same field stored in different bits, and
12603 | * should have the same type/radix/value list, and
12604 | * just differ in their bit masks. (If a field isn't
12605 | * a bitfield, but can be, say, 1 or 2 bytes long,
12606 | * it can just be made FT_UINT16, meaning the
12607 | * *maximum* length is 2 bytes, and be used
12608 | * for all lengths.)
12609 | */
12610 | if (hfinfo->same_name_prev_id != -1)
12611 | continue;
12612 |
12613 | if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12614 | matched = true1;
12615 | printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12616 | }
12617 | }
12618 | }
12619 | return matched;
12620 | }
12621 |
12622 | /* Dumps field types and descriptive names to stdout. An independent
12623 | * program can take this output and format it into nice tables or HTML or
12624 | * whatever.
12625 | *
12626 | * There is one record per line. The fields are tab-delimited.
12627 | *
12628 | * Field 1 = field type name, e.g. FT_UINT8
12629 | * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
12630 | */
12631 | void
12632 | proto_registrar_dump_ftypes(void)
12633 | {
12634 | int fte;
12635 |
12636 | for (fte = 0; fte < FT_NUM_TYPES; fte++) {
12637 | printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
12638 | }
12639 | }
12640 |
12641 | /* This function indicates whether it's possible to construct a
12642 | * "match selected" display filter string for the specified field,
12643 | * returns an indication of whether it's possible, and, if it's
12644 | * possible and "filter" is non-null, constructs the filter and
12645 | * sets "*filter" to point to it.
12646 | * You do not need to [g_]free() this string since it will be automatically
12647 | * freed once the next packet is dissected.
12648 | */
12649 | static bool_Bool
12650 | construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt,
12651 | char **filter)
12652 | {
12653 | const header_field_info *hfinfo;
12654 | int start, length, length_remaining;
12655 |
12656 | if (!finfo)
12657 | return false0;
12658 |
12659 | hfinfo = finfo->hfinfo;
12660 | DISSECTOR_ASSERT(hfinfo)((void) ((hfinfo) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 12660, "hfinfo"))));
12661 |
12662 | /* If we have BASE_NONE and strings (a non-NULL FIELDCONVERT),
12663 | * then "the numeric value ... is not used when preparing
12664 | * filters for the field in question." If it's any other
12665 | * base, we'll generate the filter normally (which will
12666 | * be numeric, even though the human-readable string does
12667 | * work for filtering.)
12668 | *
12669 | * XXX - It might be nice to use fvalue_to_string_repr() in
12670 | * "proto_item_fill_label()" as well, although, there, you'd
12671 | * have to deal with the base *and* with resolved values for
12672 | * addresses.
12673 | *
12674 | * Perhaps in addition to taking the repr type (DISPLAY
12675 | * or DFILTER) and the display (base), fvalue_to_string_repr()
12676 | * should have the the "strings" values in the header_field_info
12677 | * structure for the field as a parameter, so it can have
12678 | * if the field is Boolean or an enumerated integer type,
12679 | * the tables used to generate human-readable values.
12680 | */
12681 | if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_NONE) {
12682 | const char *str = NULL((void*)0);
12683 |
12684 | switch (hfinfo->type) {
12685 |
12686 | case FT_INT8:
12687 | case FT_INT16:
12688 | case FT_INT24:
12689 | case FT_INT32:
12690 | str = hf_try_val_to_str(fvalue_get_sinteger(finfo->value), hfinfo);
12691 | break;
12692 |
12693 | case FT_CHAR:
12694 | case FT_UINT8:
12695 | case FT_UINT16:
12696 | case FT_UINT24:
12697 | case FT_UINT32:
12698 | str = hf_try_val_to_str(fvalue_get_uinteger(finfo->value), hfinfo);
12699 | break;
12700 |
12701 | default:
12702 | break;
12703 | }
12704 |
12705 | if (str != NULL((void*)0) && filter != NULL((void*)0)) {
12706 | *filter = wmem_strdup_printf(NULL((void*)0), "%s == \"%s\"", hfinfo->abbrev, str);
12707 | return true1;
12708 | }
12709 | }
12710 |
12711 | switch (hfinfo->type) {
12712 |
12713 | case FT_PROTOCOL:
12714 | if (filter != NULL((void*)0))
12715 | *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12716 | break;
12717 |
12718 | case FT_NONE:
12719 | /*
12720 | * If the length is 0, just match the name of the
12721 | * field.
12722 | *
12723 | * (Also check for negative values, just in case,
12724 | * as we'll cast it to an unsigned value later.)
12725 | */
12726 | length = finfo->length;
12727 | if (length == 0) {
12728 | if (filter != NULL((void*)0))
12729 | *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12730 | break;
12731 | }
12732 | if (length < 0)
12733 | return false0;
12734 |
12735 | /*
12736 | * This doesn't have a value, so we'd match
12737 | * on the raw bytes at this address.
12738 | *
12739 | * Should we be allowed to access to the raw bytes?
12740 | * If "edt" is NULL, the answer is "no".
12741 | */
12742 | if (edt == NULL((void*)0))
12743 | return false0;
12744 |
12745 | /*
12746 | * Is this field part of the raw frame tvbuff?
12747 | * If not, we can't use "frame[N:M]" to match
12748 | * it.
12749 | *
12750 | * XXX - should this be frame-relative, or
12751 | * protocol-relative?
12752 | *
12753 | * XXX - does this fallback for non-registered
12754 | * fields even make sense?
12755 | */
12756 | if (finfo->ds_tvb != edt->tvb)
12757 | return false0; /* you lose */
12758 |
12759 | /*
12760 | * Don't go past the end of that tvbuff.
12761 | */
12762 | length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
12763 | if (length > length_remaining)
12764 | length = length_remaining;
12765 | if (length <= 0)
12766 | return false0;
12767 |
12768 | if (filter != NULL((void*)0)) {
12769 | start = finfo->start;
12770 | char *str = bytes_to_dfilter_repr(NULL((void*)0), tvb_get_ptr(finfo->ds_tvb, start, length), length);
12771 | *filter = wmem_strdup_printf(NULL((void*)0), "frame[%d:%d] == %s", finfo->start, length, str);
12772 | wmem_free(NULL((void*)0), str);
12773 | }
12774 | break;
12775 |
12776 | /* By default, use the fvalue's "to_string_repr" method. */
12777 | default:
12778 | if (filter != NULL((void*)0)) {
12779 | char *str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
12780 | *filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", hfinfo->abbrev, str);
12781 | wmem_free(NULL((void*)0), str);
12782 | }
12783 | break;
12784 | }
12785 |
12786 | return true1;
12787 | }
12788 |
12789 | /*
12790 | * Returns true if we can do a "match selected" on the field, false
12791 | * otherwise.
12792 | */
12793 | bool_Bool
12794 | proto_can_match_selected(const field_info *finfo, epan_dissect_t *edt)
12795 | {
12796 | return construct_match_selected_string(finfo, edt, NULL((void*)0));
12797 | }
12798 |
12799 | /* This function attempts to construct a "match selected" display filter
12800 | * string for the specified field; if it can do so, it returns a pointer
12801 | * to the string, otherwise it returns NULL.
12802 | *
12803 | * The string is wmem allocated and must be freed with "wmem_free(NULL, ...)".
12804 | */
12805 | char *
12806 | proto_construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt)
12807 | {
12808 | char *filter = NULL((void*)0);
12809 |
12810 | if (!construct_match_selected_string(finfo, edt, &filter))
12811 | {
12812 | wmem_free(NULL((void*)0), filter);
12813 | return NULL((void*)0);
12814 | }
12815 | return filter;
12816 | }
12817 |
12818 | /* This function is common code for all proto_tree_add_bitmask... functions.
12819 | */
12820 |
12821 | static bool_Bool
12822 | proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
12823 | const int len, const int ett, int * const *fields,
12824 | const int flags, bool_Bool first,
12825 | bool_Bool use_parent_tree,
12826 | proto_tree* tree, uint64_t value)
12827 | {
12828 | uint64_t available_bits = UINT64_MAX(18446744073709551615UL);
12829 | uint64_t bitmask = 0;
12830 | uint64_t tmpval;
12831 | header_field_info *hf;
12832 | uint32_t integer32;
12833 | int bit_offset;
12834 | int no_of_bits;
12835 |
12836 | if (!*fields)
12837 | 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" );
12838 |
12839 | if (len < 0 || len > 8)
12840 | REPORT_DISSECTOR_BUG("Invalid len: %d", len)proto_report_dissector_bug("Invalid len: %d", len);
12841 | /**
12842 | * packet-frame.c uses len=0 since the value is taken from the packet
12843 | * metadata, not the packet bytes. In that case, assume that all bits
12844 | * in the provided value are valid.
12845 | */
12846 | if (len > 0) {
12847 | available_bits >>= (8 - (unsigned)len)*8;
12848 | }
12849 |
12850 | if (use_parent_tree == false0)
12851 | tree = proto_item_add_subtree(item, ett);
12852 |
12853 | while (*fields) {
12854 | uint64_t present_bits;
12855 | 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", 12855, __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", 12855 , "**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", 12855, "gpa_hfinfo.hfi[**fields] != ((void*)0)" , "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[**fields];;
12856 | 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", 12856 , "hf->bitmask != 0", hf->abbrev))));
12857 |
12858 | bitmask |= hf->bitmask;
12859 |
12860 | /* Skip fields that aren't fully present */
12861 | present_bits = available_bits & hf->bitmask;
12862 | if (present_bits != hf->bitmask) {
12863 | fields++;
12864 | continue;
12865 | }
12866 |
12867 | switch (hf->type) {
12868 | case FT_CHAR:
12869 | case FT_UINT8:
12870 | case FT_UINT16:
12871 | case FT_UINT24:
12872 | case FT_UINT32:
12873 | proto_tree_add_uint(tree, **fields, tvb, offset, len, (uint32_t)value);
12874 | break;
12875 |
12876 | case FT_INT8:
12877 | case FT_INT16:
12878 | case FT_INT24:
12879 | case FT_INT32:
12880 | proto_tree_add_int(tree, **fields, tvb, offset, len, (int32_t)value);
12881 | break;
12882 |
12883 | case FT_UINT40:
12884 | case FT_UINT48:
12885 | case FT_UINT56:
12886 | case FT_UINT64:
12887 | proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
12888 | break;
12889 |
12890 | case FT_INT40:
12891 | case FT_INT48:
12892 | case FT_INT56:
12893 | case FT_INT64:
12894 | proto_tree_add_int64(tree, **fields, tvb, offset, len, (int64_t)value);
12895 | break;
12896 |
12897 | case FT_BOOLEAN:
12898 | proto_tree_add_boolean(tree, **fields, tvb, offset, len, value);
12899 | break;
12900 |
12901 | default:
12902 | 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))
12903 | 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))
12904 | 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))
12905 | 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));
12906 | break;
12907 | }
12908 | if (flags & BMT_NO_APPEND0x01) {
12909 | fields++;
12910 | continue;
12911 | }
12912 | tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
12913 |
12914 | /* XXX: README.developer and the comments have always defined
12915 | * BMT_NO_INT as "only boolean flags are added to the title /
12916 | * don't add non-boolean (integral) fields", but the
12917 | * implementation has always added BASE_CUSTOM and fields with
12918 | * value_strings, though not fields with unit_strings.
12919 | * Possibly this is because some dissectors use a FT_UINT8
12920 | * with a value_string for fields that should be a FT_BOOLEAN.
12921 | */
12922 | switch (hf->type) {
12923 | case FT_CHAR:
12924 | if (hf->display == BASE_CUSTOM) {
12925 | char lbl[ITEM_LABEL_LENGTH240];
12926 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12927 |
12928 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 12928, "fmtfunc"))));
12929 | fmtfunc(lbl, (uint32_t) tmpval);
12930 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12931 | hf->name, lbl);
12932 | first = false0;
12933 | }
12934 | else if (hf->strings) {
12935 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12936 | hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12937 | first = false0;
12938 | }
12939 | else if (!(flags & BMT_NO_INT0x02)) {
12940 | char buf[32];
12941 | const char *out;
12942 |
12943 | if (!first) {
12944 | proto_item_append_text(item, ", ");
12945 | }
12946 |
12947 | out = hfinfo_char_value_format(hf, buf, (uint32_t) tmpval);
12948 | proto_item_append_text(item, "%s: %s", hf->name, out);
12949 | first = false0;
12950 | }
12951 |
12952 | break;
12953 |
12954 | case FT_UINT8:
12955 | case FT_UINT16:
12956 | case FT_UINT24:
12957 | case FT_UINT32:
12958 | if (hf->display == BASE_CUSTOM) {
12959 | char lbl[ITEM_LABEL_LENGTH240];
12960 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12961 |
12962 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 12962, "fmtfunc"))));
12963 | fmtfunc(lbl, (uint32_t) tmpval);
12964 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12965 | hf->name, lbl);
12966 | first = false0;
12967 | }
12968 | else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12969 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12970 | hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12971 | first = false0;
12972 | }
12973 | else if (!(flags & BMT_NO_INT0x02)) {
12974 | char buf[NUMBER_LABEL_LENGTH80];
12975 | const char *out = NULL((void*)0);
12976 |
12977 | if (!first) {
12978 | proto_item_append_text(item, ", ");
12979 | }
12980 |
12981 | if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12982 | out = hf_try_val_to_str((uint32_t) tmpval, hf);
12983 | }
12984 | if (out == NULL((void*)0)) {
12985 | out = hfinfo_number_value_format(hf, buf, (uint32_t) tmpval);
12986 | }
12987 | proto_item_append_text(item, "%s: %s", hf->name, out);
12988 | if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12989 | proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12990 | }
12991 | first = false0;
12992 | }
12993 |
12994 | break;
12995 |
12996 | case FT_INT8:
12997 | case FT_INT16:
12998 | case FT_INT24:
12999 | case FT_INT32:
13000 | integer32 = (uint32_t) tmpval;
13001 | if (hf->bitmask) {
13002 | no_of_bits = ws_count_ones(hf->bitmask);
13003 | integer32 = ws_sign_ext32(integer32, no_of_bits);
13004 | }
13005 | if (hf->display == BASE_CUSTOM) {
13006 | char lbl[ITEM_LABEL_LENGTH240];
13007 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
13008 |
13009 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 13009, "fmtfunc"))));
13010 | fmtfunc(lbl, (int32_t) integer32);
13011 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13012 | hf->name, lbl);
13013 | first = false0;
13014 | }
13015 | else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13016 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13017 | hf->name, hf_try_val_to_str_const((int32_t) integer32, hf, "Unknown"));
13018 | first = false0;
13019 | }
13020 | else if (!(flags & BMT_NO_INT0x02)) {
13021 | char buf[NUMBER_LABEL_LENGTH80];
13022 | const char *out = NULL((void*)0);
13023 |
13024 | if (!first) {
13025 | proto_item_append_text(item, ", ");
13026 | }
13027 |
13028 | if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13029 | out = hf_try_val_to_str((int32_t) integer32, hf);
13030 | }
13031 | if (out == NULL((void*)0)) {
13032 | out = hfinfo_number_value_format(hf, buf, (int32_t) integer32);
13033 | }
13034 | proto_item_append_text(item, "%s: %s", hf->name, out);
13035 | if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13036 | proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
13037 | }
13038 | first = false0;
13039 | }
13040 |
13041 | break;
13042 |
13043 | case FT_UINT40:
13044 | case FT_UINT48:
13045 | case FT_UINT56:
13046 | case FT_UINT64:
13047 | if (hf->display == BASE_CUSTOM) {
13048 | char lbl[ITEM_LABEL_LENGTH240];
13049 | const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
13050 |
13051 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 13051, "fmtfunc"))));
13052 | fmtfunc(lbl, tmpval);
13053 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13054 | hf->name, lbl);
13055 | first = false0;
13056 | }
13057 | else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13058 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13059 | hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
13060 | first = false0;
13061 | }
13062 | else if (!(flags & BMT_NO_INT0x02)) {
13063 | char buf[NUMBER_LABEL_LENGTH80];
13064 | const char *out = NULL((void*)0);
13065 |
13066 | if (!first) {
13067 | proto_item_append_text(item, ", ");
13068 | }
13069 |
13070 | if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13071 | out = hf_try_val64_to_str(tmpval, hf);
13072 | }
13073 | if (out == NULL((void*)0)) {
13074 | out = hfinfo_number_value_format64(hf, buf, tmpval);
13075 | }
13076 | proto_item_append_text(item, "%s: %s", hf->name, out);
13077 | if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13078 | proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
13079 | }
13080 | first = false0;
13081 | }
13082 |
13083 | break;
13084 |
13085 | case FT_INT40:
13086 | case FT_INT48:
13087 | case FT_INT56:
13088 | case FT_INT64:
13089 | if (hf->bitmask) {
13090 | no_of_bits = ws_count_ones(hf->bitmask);
13091 | tmpval = ws_sign_ext64(tmpval, no_of_bits);
13092 | }
13093 | if (hf->display == BASE_CUSTOM) {
13094 | char lbl[ITEM_LABEL_LENGTH240];
13095 | const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
13096 |
13097 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 13097, "fmtfunc"))));
13098 | fmtfunc(lbl, (int64_t) tmpval);
13099 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13100 | hf->name, lbl);
13101 | first = false0;
13102 | }
13103 | else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13104 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13105 | hf->name, hf_try_val64_to_str_const((int64_t) tmpval, hf, "Unknown"));
13106 | first = false0;
13107 | }
13108 | else if (!(flags & BMT_NO_INT0x02)) {
13109 | char buf[NUMBER_LABEL_LENGTH80];
13110 | const char *out = NULL((void*)0);
13111 |
13112 | if (!first) {
13113 | proto_item_append_text(item, ", ");
13114 | }
13115 |
13116 | if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13117 | out = hf_try_val64_to_str((int64_t) tmpval, hf);
13118 | }
13119 | if (out == NULL((void*)0)) {
13120 | out = hfinfo_number_value_format64(hf, buf, (int64_t) tmpval);
13121 | }
13122 | proto_item_append_text(item, "%s: %s", hf->name, out);
13123 | if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13124 | proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
13125 | }
13126 | first = false0;
13127 | }
13128 |
13129 | break;
13130 |
13131 | case FT_BOOLEAN:
13132 | if (hf->strings && !(flags & BMT_NO_TFS0x08)) {
13133 | /* If we have true/false strings, emit full - otherwise messages
13134 | might look weird */
13135 | const struct true_false_string *tfs =
13136 | (const struct true_false_string *)hf->strings;
13137 |
13138 | if (tmpval) {
13139 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13140 | hf->name, tfs->true_string);
13141 | first = false0;
13142 | } else if (!(flags & BMT_NO_FALSE0x04)) {
13143 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13144 | hf->name, tfs->false_string);
13145 | first = false0;
13146 | }
13147 | } else if (hf->bitmask & value) {
13148 | /* If the flag is set, show the name */
13149 | proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
13150 | first = false0;
13151 | }
13152 | break;
13153 | default:
13154 | 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))
13155 | 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))
13156 | 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))
13157 | 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));
13158 | break;
13159 | }
13160 |
13161 | fields++;
13162 | }
13163 |
13164 | /* XXX: We don't pass the hfi into this function. Perhaps we should,
13165 | * but then again most dissectors don't set the bitmask field for
13166 | * the higher level bitmask hfi, so calculate the bitmask from the
13167 | * fields present. */
13168 | if (item) {
13169 | bit_offset = len*8 - 1 - ws_ilog2(bitmask);
13170 | no_of_bits = ws_ilog2(bitmask) - ws_ctz(bitmask) + 1;
13171 | 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);
13172 | 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);
13173 | }
13174 | return first;
13175 | }
13176 |
13177 | /* This function will dissect a sequence of bytes that describe a
13178 | * bitmask and supply the value of that sequence through a pointer.
13179 | * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13180 | * to be dissected.
13181 | * This field will form an expansion under which the individual fields of the
13182 | * bitmask is dissected and displayed.
13183 | * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13184 | *
13185 | * fields is an array of pointers to int that lists all the fields of the
13186 | * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13187 | * or another integer of the same type/size as hf_hdr with a mask specified.
13188 | * This array is terminated by a NULL entry.
13189 | *
13190 | * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13191 | * FT_integer fields that have a value_string attached will have the
13192 | * matched string displayed on the expansion line.
13193 | */
13194 | proto_item *
13195 | proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
13196 | const unsigned offset, const int hf_hdr,
13197 | const int ett, int * const *fields,
13198 | const unsigned encoding, uint64_t *retval)
13199 | {
13200 | 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);
13201 | }
13202 |
13203 | /* This function will dissect a sequence of bytes that describe a
13204 | * bitmask.
13205 | * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13206 | * to be dissected.
13207 | * This field will form an expansion under which the individual fields of the
13208 | * bitmask is dissected and displayed.
13209 | * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13210 | *
13211 | * fields is an array of pointers to int that lists all the fields of the
13212 | * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13213 | * or another integer of the same type/size as hf_hdr with a mask specified.
13214 | * This array is terminated by a NULL entry.
13215 | *
13216 | * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13217 | * FT_integer fields that have a value_string attached will have the
13218 | * matched string displayed on the expansion line.
13219 | */
13220 | proto_item *
13221 | proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
13222 | const unsigned offset, const int hf_hdr,
13223 | const int ett, int * const *fields,
13224 | const unsigned encoding)
13225 | {
13226 | return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13227 | }
13228 |
13229 | /* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13230 | * what data is appended to the header.
13231 | */
13232 | proto_item *
13233 | proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13234 | const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags,
13235 | uint64_t *retval)
13236 | {
13237 | proto_item *item = NULL((void*)0);
13238 | header_field_info *hf;
13239 | int len;
13240 | uint64_t value;
13241 |
13242 | PROTO_REGISTRAR_GET_NTH(hf_hdr,hf)if((hf_hdr == 0 || (unsigned)hf_hdr > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 13242, __func__, "Unregistered hf! index=%d" , hf_hdr); ((void) ((hf_hdr > 0 && (unsigned)hf_hdr < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13242 , "hf_hdr > 0 && (unsigned)hf_hdr < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_hdr] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13242, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)" , "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];;
13243 | DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf)((void) (((((((hf)->type) == FT_INT8 || ((hf)->type) == FT_INT16 || ((hf)->type) == FT_INT24 || ((hf)->type) == FT_INT32) || (((hf)->type) == FT_INT40 || ((hf)->type) == FT_INT48 || ((hf)->type) == FT_INT56 || ((hf)->type ) == FT_INT64)) || ((((hf)->type) == FT_CHAR || ((hf)-> type) == FT_UINT8 || ((hf)->type) == FT_UINT16 || ((hf)-> type) == FT_UINT24 || ((hf)->type) == FT_UINT32 || ((hf)-> type) == FT_FRAMENUM) || (((hf)->type) == FT_UINT40 || ((hf )->type) == FT_UINT48 || ((hf)->type) == FT_UINT56 || ( (hf)->type) == FT_UINT64)))) ? (void)0 : proto_report_dissector_bug ("%s:%u: field %s is not of type FT_CHAR or an FT_{U}INTn type" , "epan/proto.c", 13243, (hf)->abbrev)));
13244 | len = ftype_wire_size(hf->type);
13245 | value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13246 |
13247 | if (parent_tree) {
13248 | item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13249 | proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13250 | flags, false0, false0, NULL((void*)0), value);
13251 | }
13252 |
13253 | *retval = value;
13254 | if (hf->bitmask) {
13255 | /* Mask out irrelevant portions */
13256 | *retval &= hf->bitmask;
13257 | /* Shift bits */
13258 | *retval >>= hfinfo_bitshift(hf);
13259 | }
13260 |
13261 | return item;
13262 | }
13263 |
13264 | /* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13265 | * what data is appended to the header.
13266 | */
13267 | proto_item *
13268 | proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13269 | const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags)
13270 | {
13271 | proto_item *item = NULL((void*)0);
13272 | header_field_info *hf;
13273 | int len;
13274 | uint64_t value;
13275 |
13276 | 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", 13276, __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", 13276 , "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", 13276, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)" , "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];;
13277 | 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", 13277, (hf)->abbrev)));
13278 |
13279 | if (parent_tree) {
13280 | len = ftype_wire_size(hf->type);
13281 | item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13282 | value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13283 | proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13284 | flags, false0, false0, NULL((void*)0), value);
13285 | }
13286 |
13287 | return item;
13288 | }
13289 |
13290 | /* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
13291 | can't be retrieved directly from tvb) */
13292 | proto_item *
13293 | proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13294 | const int hf_hdr, const int ett, int * const *fields, const uint64_t value)
13295 | {
13296 | return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
13297 | hf_hdr, ett, fields, value, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13298 | }
13299 |
13300 | /* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
13301 | WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern proto_item *
13302 | proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13303 | const int hf_hdr, const int ett, int * const *fields, const uint64_t value, const int flags)
13304 | {
13305 | proto_item *item = NULL((void*)0);
13306 | header_field_info *hf;
13307 | int len;
13308 |
13309 | 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", 13309, __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", 13309 , "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", 13309, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)" , "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];;
13310 | 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", 13310, (hf)->abbrev)));
13311 | /* the proto_tree_add_uint/_uint64() calls below
13312 | will fail if tvb==NULL and len!=0 */
13313 | len = tvb ? ftype_wire_size(hf->type) : 0;
13314 |
13315 | if (parent_tree) {
13316 | if (len <= 4)
13317 | item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (uint32_t)value);
13318 | else
13319 | item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
13320 |
13321 | proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13322 | flags, false0, false0, NULL((void*)0), value);
13323 | }
13324 |
13325 | return item;
13326 | }
13327 |
13328 | /* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
13329 | void
13330 | proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13331 | const int len, int * const *fields, const unsigned encoding)
13332 | {
13333 | uint64_t value;
13334 |
13335 | if (tree) {
13336 | value = get_uint64_value(tree, tvb, offset, len, encoding);
13337 | proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13338 | BMT_NO_APPEND0x01, false0, true1, tree, value);
13339 | }
13340 | }
13341 |
13342 | WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13343 | proto_tree_add_bitmask_list_ret_uint64(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13344 | const int len, int * const *fields, const unsigned encoding, uint64_t *retval)
13345 | {
13346 | uint64_t value;
13347 |
13348 | value = get_uint64_value(tree, tvb, offset, len, encoding);
13349 | if (tree) {
13350 | proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13351 | BMT_NO_APPEND0x01, false0, true1, tree, value);
13352 | }
13353 | if (retval) {
13354 | *retval = value;
13355 | }
13356 | }
13357 |
13358 | WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13359 | proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13360 | const int len, int * const *fields, const uint64_t value)
13361 | {
13362 | if (tree) {
13363 | proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13364 | BMT_NO_APPEND0x01, false0, true1, tree, value);
13365 | }
13366 | }
13367 |
13368 |
13369 | /* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
13370 | * This is intended to support bitmask fields whose lengths can vary, perhaps
13371 | * as the underlying standard evolves over time.
13372 | * With this API there is the possibility of being called to display more or
13373 | * less data than the dissector was coded to support.
13374 | * In such cases, it is assumed that bitmasks are extended on the MSb end.
13375 | * Thus when presented with "too much" or "too little" data, MSbits will be
13376 | * ignored or MSfields sacrificed.
13377 | *
13378 | * Only fields for which all defined bits are available are displayed.
13379 | */
13380 | proto_item *
13381 | proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
13382 | const unsigned offset, const unsigned len, const int hf_hdr,
13383 | const int ett, int * const *fields, struct expert_field* exp,
13384 | const unsigned encoding)
13385 | {
13386 | proto_item *item = NULL((void*)0);
13387 | header_field_info *hf;
13388 | unsigned decodable_len;
13389 | unsigned decodable_offset;
13390 | uint32_t decodable_value;
13391 | uint64_t value;
13392 |
13393 | 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", 13393, __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", 13393 , "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", 13393, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)" , "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];;
13394 | 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", 13394, (hf)->abbrev)));
13395 |
13396 | decodable_offset = offset;
13397 | decodable_len = MIN(len, (unsigned) ftype_wire_size(hf->type))(((len) < ((unsigned) ftype_wire_size(hf->type))) ? (len ) : ((unsigned) ftype_wire_size(hf->type)));
13398 |
13399 | /* If we are ftype_wire_size-limited,
13400 | * make sure we decode as many LSBs as possible.
13401 | */
13402 | if (encoding == ENC_BIG_ENDIAN0x00000000) {
13403 | decodable_offset += (len - decodable_len);
13404 | }
13405 |
13406 | if (parent_tree) {
13407 | decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
13408 | decodable_len, encoding);
13409 |
13410 | /* The root item covers all the bytes even if we can't decode them all */
13411 | item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
13412 | decodable_value);
13413 | }
13414 |
13415 | if (decodable_len < len) {
13416 | /* Dissector likely requires updating for new protocol revision */
13417 | expert_add_info_format(NULL((void*)0), item, exp,
13418 | "Only least-significant %d of %d bytes decoded",
13419 | decodable_len, len);
13420 | }
13421 |
13422 | if (item) {
13423 | value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
13424 | proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
13425 | ett, fields, BMT_NO_INT0x02|BMT_NO_TFS0x08, false0, false0, NULL((void*)0), value);
13426 | }
13427 |
13428 | return item;
13429 | }
13430 |
13431 | /* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
13432 | proto_item *
13433 | proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
13434 | const unsigned offset, const unsigned len,
13435 | const char *name, const char *fallback,
13436 | const int ett, int * const *fields,
13437 | const unsigned encoding, const int flags)
13438 | {
13439 | proto_item *item = NULL((void*)0);
13440 | uint64_t value;
13441 |
13442 | if (parent_tree) {
13443 | item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
13444 | value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13445 | if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13446 | flags, true1, false0, NULL((void*)0), value) && fallback) {
13447 | /* Still at first item - append 'fallback' text if any */
13448 | proto_item_append_text(item, "%s", fallback);
13449 | }
13450 | }
13451 |
13452 | return item;
13453 | }
13454 |
13455 | proto_item *
13456 | proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13457 | const unsigned bit_offset, const int no_of_bits,
13458 | const unsigned encoding)
13459 | {
13460 | header_field_info *hfinfo;
13461 | int octet_length;
13462 | int octet_offset;
13463 |
13464 | 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", 13464, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13464 , "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13464, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
13465 |
13466 | if (no_of_bits < 0) {
13467 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13468 | }
13469 | octet_length = (no_of_bits + 7) >> 3;
13470 | octet_offset = bit_offset >> 3;
13471 | test_length(hfinfo, tvb, octet_offset, octet_length, encoding);
13472 |
13473 | /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
13474 | * but only after doing a bunch more work (which we can, in the common
13475 | * case, shortcut here).
13476 | */
13477 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13478 | 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", 13478 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13478, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13478, "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", 13478, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
13479 |
13480 | return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL((void*)0), encoding);
13481 | }
13482 |
13483 | /*
13484 | * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
13485 | * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
13486 | * Offset should be given in bits from the start of the tvb.
13487 | */
13488 |
13489 | static proto_item *
13490 | _proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13491 | const unsigned bit_offset, const int no_of_bits,
13492 | uint64_t *return_value, const unsigned encoding)
13493 | {
13494 | int offset;
13495 | unsigned length;
13496 | uint8_t tot_no_bits;
13497 | char *bf_str;
13498 | char lbl_str[ITEM_LABEL_LENGTH240];
13499 | uint64_t value = 0;
13500 | uint8_t *bytes = NULL((void*)0);
13501 | size_t bytes_length = 0;
13502 |
13503 | proto_item *pi;
13504 | header_field_info *hf_field;
13505 |
13506 | /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13507 | 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", 13507, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13507 , "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13507, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex] ;;
13508 |
13509 | if (hf_field->bitmask != 0) {
13510 | 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)
13511 | " 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)
13512 | 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);
13513 | }
13514 |
13515 | if (no_of_bits < 0) {
13516 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13517 | } else if (no_of_bits == 0) {
13518 | 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)
13519 | 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);
13520 | }
13521 |
13522 | /* Byte align offset */
13523 | offset = bit_offset>>3;
13524 |
13525 | /*
13526 | * Calculate the number of octets used to hold the bits
13527 | */
13528 | tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13529 | length = (tot_no_bits + 7) >> 3;
13530 |
13531 | if (no_of_bits < 65) {
13532 | value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13533 | } else if (hf_field->type != FT_BYTES) {
13534 | 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)
13535 | 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);
13536 | return NULL((void*)0);
13537 | }
13538 |
13539 | /* Sign extend for signed types */
13540 | switch (hf_field->type) {
13541 | case FT_INT8:
13542 | case FT_INT16:
13543 | case FT_INT24:
13544 | case FT_INT32:
13545 | case FT_INT40:
13546 | case FT_INT48:
13547 | case FT_INT56:
13548 | case FT_INT64:
13549 | value = ws_sign_ext64(value, no_of_bits);
13550 | break;
13551 |
13552 | default:
13553 | break;
13554 | }
13555 |
13556 | if (return_value) {
13557 | *return_value = value;
13558 | }
13559 |
13560 | /* Coast clear. Try and fake it */
13561 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13562 | 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", 13562 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13562, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13562, "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", 13562, __func__, "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); } } };
13563 |
13564 | bf_str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13565 |
13566 | switch (hf_field->type) {
13567 | case FT_BOOLEAN:
13568 | /* Boolean field */
13569 | return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, value,
13570 | "%s = %s: %s",
13571 | bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13572 | break;
13573 |
13574 | case FT_CHAR:
13575 | pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13576 | fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13577 | break;
13578 |
13579 | case FT_UINT8:
13580 | case FT_UINT16:
13581 | case FT_UINT24:
13582 | case FT_UINT32:
13583 | pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13584 | fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13585 | break;
13586 |
13587 | case FT_INT8:
13588 | case FT_INT16:
13589 | case FT_INT24:
13590 | case FT_INT32:
13591 | pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (int32_t)value);
13592 | fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13593 | break;
13594 |
13595 | case FT_UINT40:
13596 | case FT_UINT48:
13597 | case FT_UINT56:
13598 | case FT_UINT64:
13599 | pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
13600 | fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13601 | break;
13602 |
13603 | case FT_INT40:
13604 | case FT_INT48:
13605 | case FT_INT56:
13606 | case FT_INT64:
13607 | pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (int64_t)value);
13608 | fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13609 | break;
13610 |
13611 | case FT_BYTES:
13612 | bytes = tvb_get_bits_array(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_bits, &bytes_length, encoding);
13613 | pi = proto_tree_add_bytes_with_length(tree, hfindex, tvb, offset, length, bytes, (int) bytes_length);
13614 | proto_item_fill_label(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13615 | proto_item_set_text(pi, "%s", lbl_str);
13616 | return pi;
13617 |
13618 | /* TODO: should handle FT_UINT_BYTES ? */
13619 |
13620 | default:
13621 | 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))
13622 | 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))
13623 | 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))
13624 | 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));
13625 | return NULL((void*)0);
13626 | }
13627 |
13628 | proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13629 | return pi;
13630 | }
13631 |
13632 | proto_item *
13633 | proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13634 | const unsigned bit_offset, const crumb_spec_t *crumb_spec,
13635 | uint64_t *return_value)
13636 | {
13637 | proto_item *pi;
13638 | int no_of_bits;
13639 | int octet_offset;
13640 | unsigned mask_initial_bit_offset;
13641 | unsigned mask_greatest_bit_offset;
13642 | unsigned octet_length;
13643 | uint8_t i;
13644 | char bf_str[256];
13645 | char lbl_str[ITEM_LABEL_LENGTH240];
13646 | uint64_t value;
13647 | uint64_t composite_bitmask;
13648 | uint64_t composite_bitmap;
13649 |
13650 | header_field_info *hf_field;
13651 |
13652 | /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13653 | 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", 13653, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13653 , "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13653, "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 | →
13654 |
13655 | if (hf_field->bitmask != 0) {
8 | ← | Assuming field 'bitmask' is equal to 0 | →
9 | ← | Taking false branch | →
13656 | 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)
13657 | " 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)
13658 | 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);
13659 | }
13660 |
13661 | mask_initial_bit_offset = bit_offset % 8;
13662 |
13663 | no_of_bits = 0;
13664 | value = 0;
13665 | i = 0;
13666 | mask_greatest_bit_offset = 0;
13667 | composite_bitmask = 0;
13668 | composite_bitmap = 0;
13669 |
13670 | 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 | →
13671 | uint64_t crumb_mask, crumb_value;
13672 | uint8_t crumb_end_bit_offset;
13673 |
13674 | crumb_value = tvb_get_bits64(tvb,
13675 | bit_offset + crumb_spec[i].crumb_bit_offset,
13676 | crumb_spec[i].crumb_bit_length,
13677 | ENC_BIG_ENDIAN0x00000000);
13678 | value += crumb_value;
13679 | no_of_bits += crumb_spec[i].crumb_bit_length;
13680 | 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", 13680 , "no_of_bits <= 64", "a value larger than 64 bits cannot be represented" ))));
12 | ← | Assuming 'no_of_bits' is <= 64 | →
13 | ← | '?' condition is true | →
13681 |
13682 | /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
13683 | octet containing the initial offset.
13684 | If the mask is beyond 32 bits, then give up on bit map display.
13685 | This could be improved in future, probably showing a table
13686 | of 32 or 64 bits per row */
13687 | if (mask_greatest_bit_offset
13.1 | 'mask_greatest_bit_offset' is < 32
< 32) {
14 | ← | Taking true branch | →
13688 | crumb_end_bit_offset = mask_initial_bit_offset
13689 | + crumb_spec[i].crumb_bit_offset
13690 | + crumb_spec[i].crumb_bit_length;
13691 | 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' | →
13692 |
13693 | if (crumb_end_bit_offset > mask_greatest_bit_offset) {
17 | ← | Assuming 'crumb_end_bit_offset' is <= 'mask_greatest_bit_offset' | →
18 | ← | Taking false branch | →
13694 | mask_greatest_bit_offset = crumb_end_bit_offset;
13695 | }
13696 | /* Currently the bitmap of the crumbs are only shown if
13697 | * smaller than 32 bits. Do not bother calculating the
13698 | * mask if it is larger than that. */
13699 | if (crumb_end_bit_offset
18.1 | 'crumb_end_bit_offset' is <= 32
<= 32) {
19 | ← | Taking true branch | →
13700 | 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'
13701 | composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
13702 | }
13703 | }
13704 | /* Shift left for the next segment */
13705 | value <<= crumb_spec[++i].crumb_bit_length;
13706 | }
13707 |
13708 | /* Sign extend for signed types */
13709 | switch (hf_field->type) {
13710 | case FT_INT8:
13711 | case FT_INT16:
13712 | case FT_INT24:
13713 | case FT_INT32:
13714 | case FT_INT40:
13715 | case FT_INT48:
13716 | case FT_INT56:
13717 | case FT_INT64:
13718 | value = ws_sign_ext64(value, no_of_bits);
13719 | break;
13720 | default:
13721 | break;
13722 | }
13723 |
13724 | if (return_value) {
13725 | *return_value = value;
13726 | }
13727 |
13728 | /* Coast clear. Try and fake it */
13729 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13730 | 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", 13730 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13730, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13730, "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", 13730, __func__, "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); } } };
13731 |
13732 | /* initialise the format string */
13733 | bf_str[0] = '\0';
13734 |
13735 | octet_offset = bit_offset >> 3;
13736 |
13737 | /* Round up mask length to nearest octet */
13738 | octet_length = ((mask_greatest_bit_offset + 7) >> 3);
13739 | mask_greatest_bit_offset = octet_length << 3;
13740 |
13741 | /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
13742 | It would be a useful enhancement to eliminate this restriction. */
13743 | if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
13744 | other_decode_bitfield_value(bf_str,
13745 | (uint32_t)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
13746 | (uint32_t)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
13747 | mask_greatest_bit_offset);
13748 | } else {
13749 | /* If the bitmask is too large, try to describe its contents. */
13750 | snprintf(bf_str, sizeof(bf_str), "%d bits", no_of_bits);
13751 | }
13752 |
13753 | switch (hf_field->type) {
13754 | case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
13755 | /* Boolean field */
13756 | return proto_tree_add_boolean_format(tree, hfindex,
13757 | tvb, octet_offset, octet_length, value,
13758 | "%s = %s: %s",
13759 | bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13760 | break;
13761 |
13762 | case FT_CHAR:
13763 | pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13764 | fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13765 | break;
13766 |
13767 | case FT_UINT8:
13768 | case FT_UINT16:
13769 | case FT_UINT24:
13770 | case FT_UINT32:
13771 | pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13772 | fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13773 | break;
13774 |
13775 | case FT_INT8:
13776 | case FT_INT16:
13777 | case FT_INT24:
13778 | case FT_INT32:
13779 | pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (int32_t)value);
13780 | fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13781 | break;
13782 |
13783 | case FT_UINT40:
13784 | case FT_UINT48:
13785 | case FT_UINT56:
13786 | case FT_UINT64:
13787 | pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
13788 | fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13789 | break;
13790 |
13791 | case FT_INT40:
13792 | case FT_INT48:
13793 | case FT_INT56:
13794 | case FT_INT64:
13795 | pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (int64_t)value);
13796 | fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13797 | break;
13798 |
13799 | default:
13800 | 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))
13801 | 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))
13802 | 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))
13803 | 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));
13804 | return NULL((void*)0);
13805 | }
13806 | proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13807 | return pi;
13808 | }
13809 |
13810 | void
13811 | proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const unsigned bit_offset,
13812 | const crumb_spec_t *crumb_spec, uint16_t crumb_index)
13813 | {
13814 | header_field_info *hfinfo;
13815 | int start = bit_offset >> 3;
13816 | int length = ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1;
13817 |
13818 | /* We have to duplicate this length check from proto_tree_add_text_internal in order to check for a null tree
13819 | * so that we can use the tree's memory scope in calculating the string */
13820 | if (length == -1) {
13821 | tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
13822 | } else {
13823 | tvb_ensure_bytes_exist(tvb, start, length);
13824 | }
13825 | if (!tree) return;
13826 |
13827 | 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", 13827, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13827 , "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13827, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
13828 | proto_tree_add_text_internal(tree, tvb, start, length,
13829 | "%s crumb %d of %s (decoded above)",
13830 | decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, crumb_spec[crumb_index].crumb_bit_length,
13831 | tvb_get_bits32(tvb,
13832 | bit_offset,
13833 | crumb_spec[crumb_index].crumb_bit_length,
13834 | ENC_BIG_ENDIAN0x00000000),
13835 | ENC_BIG_ENDIAN0x00000000),
13836 | crumb_index,
13837 | hfinfo->name);
13838 | }
13839 |
13840 | proto_item *
13841 | proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13842 | const unsigned bit_offset, const int no_of_bits,
13843 | uint64_t *return_value, const unsigned encoding)
13844 | {
13845 | proto_item *item;
13846 |
13847 | if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
13848 | bit_offset, no_of_bits,
13849 | return_value, encoding))) {
13850 | 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);
13851 | 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);
13852 | }
13853 | return item;
13854 | }
13855 |
13856 | static proto_item *
13857 | _proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13858 | tvbuff_t *tvb, const unsigned bit_offset,
13859 | const int no_of_bits, void *value_ptr,
13860 | const unsigned encoding, char *value_str)
13861 | {
13862 | int offset;
13863 | unsigned length;
13864 | uint8_t tot_no_bits;
13865 | char *str;
13866 | uint64_t value = 0;
13867 | header_field_info *hf_field;
13868 |
13869 | /* We do not have to return a value, try to fake it as soon as possible */
13870 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13871 | 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", 13871 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13871, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13871, "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", 13871, __func__, "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); } } };
13872 |
13873 | if (hf_field->bitmask != 0) {
13874 | 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)
13875 | " 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)
13876 | 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);
13877 | }
13878 |
13879 | if (no_of_bits < 0) {
13880 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13881 | } else if (no_of_bits == 0) {
13882 | 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)
13883 | 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);
13884 | }
13885 |
13886 | /* Byte align offset */
13887 | offset = bit_offset>>3;
13888 |
13889 | /*
13890 | * Calculate the number of octets used to hold the bits
13891 | */
13892 | tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13893 | length = tot_no_bits>>3;
13894 | /* If we are using part of the next octet, increase length by 1 */
13895 | if (tot_no_bits & 0x07)
13896 | length++;
13897 |
13898 | if (no_of_bits < 65) {
13899 | value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13900 | } else {
13901 | 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)
13902 | 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);
13903 | return NULL((void*)0);
13904 | }
13905 |
13906 | str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13907 |
13908 | (void) g_strlcat(str, " = ", 256+64);
13909 | (void) g_strlcat(str, hf_field->name, 256+64);
13910 |
13911 | /*
13912 | * This function does not receive an actual value but a dimensionless pointer to that value.
13913 | * For this reason, the type of the header field is examined in order to determine
13914 | * what kind of value we should read from this address.
13915 | * The caller of this function must make sure that for the specific header field type the address of
13916 | * a compatible value is provided.
13917 | */
13918 | switch (hf_field->type) {
13919 | case FT_BOOLEAN:
13920 | return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13921 | "%s: %s", str, value_str);
13922 | break;
13923 |
13924 | case FT_CHAR:
13925 | case FT_UINT8:
13926 | case FT_UINT16:
13927 | case FT_UINT24:
13928 | case FT_UINT32:
13929 | return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(uint32_t *)value_ptr,
13930 | "%s: %s", str, value_str);
13931 | break;
13932 |
13933 | case FT_UINT40:
13934 | case FT_UINT48:
13935 | case FT_UINT56:
13936 | case FT_UINT64:
13937 | return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13938 | "%s: %s", str, value_str);
13939 | break;
13940 |
13941 | case FT_INT8:
13942 | case FT_INT16:
13943 | case FT_INT24:
13944 | case FT_INT32:
13945 | return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(int32_t *)value_ptr,
13946 | "%s: %s", str, value_str);
13947 | break;
13948 |
13949 | case FT_INT40:
13950 | case FT_INT48:
13951 | case FT_INT56:
13952 | case FT_INT64:
13953 | return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(int64_t *)value_ptr,
13954 | "%s: %s", str, value_str);
13955 | break;
13956 |
13957 | case FT_FLOAT:
13958 | return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
13959 | "%s: %s", str, value_str);
13960 | break;
13961 |
13962 | default:
13963 | 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))
13964 | 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))
13965 | 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))
13966 | 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));
13967 | return NULL((void*)0);
13968 | }
13969 | }
13970 |
13971 | static proto_item *
13972 | proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13973 | tvbuff_t *tvb, const unsigned bit_offset,
13974 | const int no_of_bits, void *value_ptr,
13975 | const unsigned encoding, char *value_str)
13976 | {
13977 | proto_item *item;
13978 |
13979 | if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
13980 | tvb, bit_offset, no_of_bits,
13981 | value_ptr, encoding, value_str))) {
13982 | 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);
13983 | 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);
13984 | }
13985 | return item;
13986 | }
13987 |
13988 | #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); \
13989 | va_start(ap, format)__builtin_va_start(ap, format); \
13990 | dst = wmem_strdup_vprintf(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), format, ap); \
13991 | va_end(ap)__builtin_va_end(ap);
13992 |
13993 | proto_item *
13994 | proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
13995 | tvbuff_t *tvb, const unsigned bit_offset,
13996 | const int no_of_bits, uint32_t value,
13997 | const unsigned encoding,
13998 | const char *format, ...)
13999 | {
14000 | va_list ap;
14001 | char *dst;
14002 | header_field_info *hf_field;
14003 |
14004 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14005 |
14006 | 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", 14006 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14006, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14006, "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", 14006, __func__, "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); } } };
14007 |
14008 | switch (hf_field->type) {
14009 | case FT_UINT8:
14010 | case FT_UINT16:
14011 | case FT_UINT24:
14012 | case FT_UINT32:
14013 | break;
14014 |
14015 | default:
14016 | 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)
14017 | 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);
14018 | return NULL((void*)0);
14019 | }
14020 |
14021 | 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);;
14022 |
14023 | return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14024 | }
14025 |
14026 | proto_item *
14027 | proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
14028 | tvbuff_t *tvb, const unsigned bit_offset,
14029 | const int no_of_bits, uint64_t value,
14030 | const unsigned encoding,
14031 | const char *format, ...)
14032 | {
14033 | va_list ap;
14034 | char *dst;
14035 | header_field_info *hf_field;
14036 |
14037 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14038 |
14039 | 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", 14039 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14039, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14039, "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", 14039, __func__, "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); } } };
14040 |
14041 | switch (hf_field->type) {
14042 | case FT_UINT40:
14043 | case FT_UINT48:
14044 | case FT_UINT56:
14045 | case FT_UINT64:
14046 | break;
14047 |
14048 | default:
14049 | 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)
14050 | 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);
14051 | return NULL((void*)0);
14052 | }
14053 |
14054 | 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);;
14055 |
14056 | return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14057 | }
14058 |
14059 | proto_item *
14060 | proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
14061 | tvbuff_t *tvb, const unsigned bit_offset,
14062 | const int no_of_bits, float value,
14063 | const unsigned encoding,
14064 | const char *format, ...)
14065 | {
14066 | va_list ap;
14067 | char *dst;
14068 | header_field_info *hf_field;
14069 |
14070 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14071 |
14072 | 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", 14072 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14072, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14072, "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", 14072, __func__, "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); } } };
14073 |
14074 | 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", 14074, ((hf_field))->abbrev))));
14075 |
14076 | 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);;
14077 |
14078 | return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14079 | }
14080 |
14081 | proto_item *
14082 | proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
14083 | tvbuff_t *tvb, const unsigned bit_offset,
14084 | const int no_of_bits, int32_t value,
14085 | const unsigned encoding,
14086 | const char *format, ...)
14087 | {
14088 | va_list ap;
14089 | char *dst;
14090 | header_field_info *hf_field;
14091 |
14092 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14093 |
14094 | 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", 14094 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14094, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14094, "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", 14094, __func__, "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); } } };
14095 |
14096 | switch (hf_field->type) {
14097 | case FT_INT8:
14098 | case FT_INT16:
14099 | case FT_INT24:
14100 | case FT_INT32:
14101 | break;
14102 |
14103 | default:
14104 | 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)
14105 | 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);
14106 | return NULL((void*)0);
14107 | }
14108 |
14109 | 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);;
14110 |
14111 | return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14112 | }
14113 |
14114 | proto_item *
14115 | proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
14116 | tvbuff_t *tvb, const unsigned bit_offset,
14117 | const int no_of_bits, int64_t value,
14118 | const unsigned encoding,
14119 | const char *format, ...)
14120 | {
14121 | va_list ap;
14122 | char *dst;
14123 | header_field_info *hf_field;
14124 |
14125 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14126 |
14127 | 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", 14127 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14127, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14127, "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", 14127, __func__, "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); } } };
14128 |
14129 | switch (hf_field->type) {
14130 | case FT_INT40:
14131 | case FT_INT48:
14132 | case FT_INT56:
14133 | case FT_INT64:
14134 | break;
14135 |
14136 | default:
14137 | 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)
14138 | 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);
14139 | return NULL((void*)0);
14140 | }
14141 |
14142 | 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);;
14143 |
14144 | return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14145 | }
14146 |
14147 | proto_item *
14148 | proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
14149 | tvbuff_t *tvb, const unsigned bit_offset,
14150 | const int no_of_bits, uint64_t value,
14151 | const unsigned encoding,
14152 | const char *format, ...)
14153 | {
14154 | va_list ap;
14155 | char *dst;
14156 | header_field_info *hf_field;
14157 |
14158 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14159 |
14160 | 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", 14160 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14160, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14160, "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", 14160, __func__, "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); } } };
14161 |
14162 | 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" , 14162, ((hf_field))->abbrev))));
14163 |
14164 | 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);;
14165 |
14166 | return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14167 | }
14168 |
14169 | proto_item *
14170 | proto_tree_add_ts_23_038_7bits_packed_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14171 | const unsigned bit_offset, const int no_of_chars)
14172 | {
14173 | proto_item *pi;
14174 | header_field_info *hfinfo;
14175 | int byte_length;
14176 | int byte_offset;
14177 | char *string;
14178 |
14179 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14180 |
14181 | 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", 14181 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14181, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14181, "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", 14181, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
14182 |
14183 | 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" , 14183, ((hfinfo))->abbrev))));
14184 |
14185 | byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14186 | byte_offset = bit_offset >> 3;
14187 |
14188 | string = tvb_get_ts_23_038_7bits_string_packed(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14189 |
14190 | pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14191 | DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14191, "byte_length >= 0" ))));
14192 | proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14193 |
14194 | return pi;
14195 | }
14196 |
14197 | proto_item *
14198 | proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14199 | const unsigned bit_offset, const int no_of_chars)
14200 | {
14201 | proto_item *pi;
14202 | header_field_info *hfinfo;
14203 | int byte_length;
14204 | int byte_offset;
14205 | char *string;
14206 |
14207 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14208 |
14209 | 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", 14209 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14209, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14209, "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", 14209, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
14210 |
14211 | 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" , 14211, ((hfinfo))->abbrev))));
14212 |
14213 | byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14214 | byte_offset = bit_offset >> 3;
14215 |
14216 | string = tvb_get_ascii_7bits_string(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14217 |
14218 | pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14219 | DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14219, "byte_length >= 0" ))));
14220 | proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14221 |
14222 | return pi;
14223 | }
14224 |
14225 | const value_string proto_checksum_vals[] = {
14226 | { PROTO_CHECKSUM_E_BAD, "Bad" },
14227 | { PROTO_CHECKSUM_E_GOOD, "Good" },
14228 | { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
14229 | { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
14230 | { PROTO_CHECKSUM_E_ILLEGAL, "Illegal" },
14231 |
14232 | { 0, NULL((void*)0) }
14233 | };
14234 |
14235 | #define PROTO_CHECKSUM_COMPUTED_USED(0x01|0x02|0x10) (PROTO_CHECKSUM_VERIFY0x01|PROTO_CHECKSUM_GENERATED0x02|PROTO_CHECKSUM_NOT_PRESENT0x10)
14236 |
14237 | proto_item *
14238 | proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14239 | const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14240 | packet_info *pinfo, uint32_t computed_checksum, const unsigned encoding, const unsigned flags)
14241 | {
14242 | header_field_info *hfinfo;
14243 | uint32_t checksum;
14244 | uint32_t len;
14245 | proto_item* ti = NULL((void*)0);
14246 | proto_item* ti2;
14247 | bool_Bool incorrect_checksum = true1;
14248 |
14249 | 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", 14249, __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", 14249 , "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", 14249, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum ];;
14250 |
14251 | switch (hfinfo->type) {
14252 | case FT_UINT8:
14253 | len = 1;
14254 | break;
14255 | case FT_UINT16:
14256 | len = 2;
14257 | break;
14258 | case FT_UINT24:
14259 | len = 3;
14260 | break;
14261 | case FT_UINT32:
14262 | len = 4;
14263 | break;
14264 | default:
14265 | 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)
14266 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32" , hfinfo->abbrev);
14267 | }
14268 |
14269 | if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14270 | ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, len, 0, "[missing]");
14271 | proto_item_set_generated(ti);
14272 | // Backward compatible with use of -1
14273 | if (hf_checksum_status > 0) {
14274 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, len, PROTO_CHECKSUM_E_NOT_PRESENT);
14275 | proto_item_set_generated(ti2);
14276 | }
14277 | return ti;
14278 | }
14279 |
14280 | if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14281 | ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, len, computed_checksum);
14282 | proto_item_set_generated(ti);
14283 | } else {
14284 | ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
14285 | if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14286 | if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14287 | if (computed_checksum == 0) {
14288 | proto_item_append_text(ti, " [correct]");
14289 | // Backward compatible with use of -1
14290 | if (hf_checksum_status > 0) {
14291 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14292 | proto_item_set_generated(ti2);
14293 | }
14294 | incorrect_checksum = false0;
14295 | } else if (flags & PROTO_CHECKSUM_IN_CKSUM0x04) {
14296 | computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
14297 | /* XXX - This can't distinguish between "shouldbe"
14298 | * 0x0000 and 0xFFFF unless we know whether there
14299 | * were any nonzero bits (other than the checksum).
14300 | * Protocols should not use this path if they might
14301 | * have an all zero packet.
14302 | * Some implementations put the wrong zero; maybe
14303 | * we should have a special expert info for that?
14304 | */
14305 | }
14306 | } else {
14307 | if (checksum == computed_checksum) {
14308 | proto_item_append_text(ti, " [correct]");
14309 | // Backward compatible with use of -1
14310 | if (hf_checksum_status > 0) {
14311 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14312 | proto_item_set_generated(ti2);
14313 | }
14314 | incorrect_checksum = false0;
14315 | }
14316 | }
14317 |
14318 | if (incorrect_checksum) {
14319 | // Backward compatible with use of -1
14320 | if (hf_checksum_status > 0) {
14321 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14322 | proto_item_set_generated(ti2);
14323 | }
14324 | if (flags & PROTO_CHECKSUM_ZERO0x08) {
14325 | proto_item_append_text(ti, " [incorrect]");
14326 | if (bad_checksum_expert != NULL((void*)0))
14327 | expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14328 | } else {
14329 | proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
14330 | if (bad_checksum_expert != NULL((void*)0))
14331 | 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);
14332 | }
14333 | }
14334 | } else {
14335 | // Backward compatible with use of -1
14336 | if (hf_checksum_status > 0) {
14337 | proto_item_append_text(ti, " [unverified]");
14338 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14339 | proto_item_set_generated(ti2);
14340 | }
14341 | }
14342 | }
14343 |
14344 | return ti;
14345 | }
14346 |
14347 | proto_item *
14348 | proto_tree_add_checksum_bytes(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14349 | const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14350 | packet_info *pinfo, const uint8_t *computed_checksum, size_t checksum_len, const unsigned flags)
14351 | {
14352 | header_field_info *hfinfo;
14353 | uint8_t *checksum = NULL((void*)0);
14354 | proto_item* ti = NULL((void*)0);
14355 | proto_item* ti2;
14356 | bool_Bool incorrect_checksum = true1;
14357 |
14358 | 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", 14358, __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", 14358 , "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", 14358, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum ];;
14359 |
14360 | 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", 14360, ((hfinfo))->abbrev))));
14361 |
14362 | /* Make sure a NULL computed_checksum isn't dereferenced.
14363 | * If checksum_len is 0 it probably won't crash, but in the VERIFY
14364 | * case memcmp(NULL, checksum, 0) is UB until C2y, and in the other
14365 | * cases the behavior is unexpected and still a programmer error;
14366 | * proto_tree_add_bytes retrieves it from the tvb, thus neither
14367 | * _NOT_PRESENT nor _GENERATED is correct.
14368 | */
14369 | DISSECTOR_ASSERT(computed_checksum || ((flags & PROTO_CHECKSUM_COMPUTED_USED) == PROTO_CHECKSUM_NO_FLAGS))((void) ((computed_checksum || ((flags & (0x01|0x02|0x10) ) == 0x00)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 14369, "computed_checksum || ((flags & (0x01|0x02|0x10)) == 0x00)" ))));
14370 |
14371 | if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14372 | ti = proto_tree_add_bytes_format_value(tree, hf_checksum, tvb, offset, (int)checksum_len, 0, "[missing]");
14373 | proto_item_set_generated(ti);
14374 | // Backward compatible with use of -1
14375 | if (hf_checksum_status > 0) {
14376 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, (int)checksum_len, PROTO_CHECKSUM_E_NOT_PRESENT);
14377 | proto_item_set_generated(ti2);
14378 | }
14379 | return ti;
14380 | }
14381 |
14382 | if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14383 | ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, computed_checksum);
14384 | proto_item_set_generated(ti);
14385 | return ti;
14386 | }
14387 |
14388 | checksum = tvb_memdup(pinfo->pool, tvb, offset, checksum_len);
14389 | ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, checksum);
14390 | if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14391 | if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14392 | bool_Bool non_zero_flag = false0;
14393 | for (size_t index = 0; index < checksum_len; index++) {
14394 | if (computed_checksum[index]) {
14395 | non_zero_flag = true1;
14396 | break;
14397 | }
14398 | }
14399 | if (!non_zero_flag) {
14400 | proto_item_append_text(ti, " [correct]");
14401 | // Backward compatible with use of -1
14402 | if (hf_checksum_status > 0) {
14403 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14404 | proto_item_set_generated(ti2);
14405 | }
14406 | incorrect_checksum = false0;
14407 | }
14408 | } else {
14409 | if (memcmp(computed_checksum, checksum, checksum_len) == 0) {
14410 | proto_item_append_text(ti, " [correct]");
14411 | // Backward compatible with use of -1
14412 | if (hf_checksum_status > 0) {
14413 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14414 | proto_item_set_generated(ti2);
14415 | }
14416 | incorrect_checksum = false0;
14417 | }
14418 | }
14419 |
14420 | if (incorrect_checksum) {
14421 | // Backward compatible with use of -1
14422 | if (hf_checksum_status > 0) {
14423 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14424 | proto_item_set_generated(ti2);
14425 | }
14426 | if (flags & PROTO_CHECKSUM_ZERO0x08) {
14427 | proto_item_append_text(ti, " [incorrect]");
14428 | if (bad_checksum_expert != NULL((void*)0))
14429 | expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14430 | } else {
14431 | char *computed_checksum_str = bytes_to_str_maxlen(pinfo->pool, computed_checksum, checksum_len, 0);
14432 | proto_item_append_text(ti, " incorrect, should be 0x%s", computed_checksum_str);
14433 | if (bad_checksum_expert != NULL((void*)0))
14434 | expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s [should be 0x%s]", expert_get_summary(bad_checksum_expert), computed_checksum_str);
14435 | }
14436 | }
14437 | } else {
14438 | // Backward compatible with use of -1
14439 | if (hf_checksum_status > 0) {
14440 | proto_item_append_text(ti, " [unverified]");
14441 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14442 | proto_item_set_generated(ti2);
14443 | }
14444 | }
14445 |
14446 | return ti;
14447 | }
14448 |
14449 | unsigned char
14450 | proto_check_field_name(const char *field_name)
14451 | {
14452 | return module_check_valid_name(field_name, false0);
14453 | }
14454 |
14455 | unsigned char
14456 | proto_check_field_name_lower(const char *field_name)
14457 | {
14458 | return module_check_valid_name(field_name, true1);
14459 | }
14460 |
14461 | bool_Bool
14462 | tree_expanded(int tree_type)
14463 | {
14464 | if (tree_type <= 0) {
14465 | return false0;
14466 | }
14467 | 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", 14467, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types" ); } while (0);
14468 | return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
14469 | }
14470 |
14471 | void
14472 | tree_expanded_set(int tree_type, bool_Bool value)
14473 | {
14474 | 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", 14474, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types" ); } while (0);
14475 |
14476 | if (value)
14477 | tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
14478 | else
14479 | tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
14480 | }
14481 |
14482 | /*
14483 | * Editor modelines - https://www.wireshark.org/tools/modelines.html
14484 | *
14485 | * Local variables:
14486 | * c-basic-offset: 8
14487 | * tab-width: 8
14488 | * indent-tabs-mode: t
14489 | * End:
14490 | *
14491 | * vi: set shiftwidth=8 tabstop=8 noexpandtab:
14492 | * :indentSize=8:tabSize=8:noTabs=false:
14493 | */