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 LOG_DOMAIN_EPAN
13 
14 #include <stdio.h>
15 #include <string.h>
16 #include <glib.h>
17 #include <float.h>
18 #include <errno.h>
19 
20 #include <wsutil/bits_ctz.h>
21 #include <wsutil/bits_count_ones.h>
22 #include <wsutil/sign_ext.h>
23 #include <wsutil/utf8_entities.h>
24 #include <wsutil/json_dumper.h>
25 #include <wsutil/wslog.h>
26 #include <wsutil/ws_assert.h>
27 
28 #include <ftypes/ftypes-int.h>
29 
30 #include "packet.h"
31 #include "exceptions.h"
32 #include "ptvcursor.h"
33 #include "strutil.h"
34 #include "addr_resolv.h"
35 #include "address_types.h"
36 #include "oids.h"
37 #include "proto.h"
38 #include "epan_dissect.h"
39 #include "tvbuff.h"
40 #include <epan/wmem_scopes.h>
41 #include "charsets.h"
42 #include "column-utils.h"
43 #include "to_str.h"
44 #include "osi-utils.h"
45 #include "expert.h"
46 #include "show_exception.h"
47 #include "in_cksum.h"
48 #include "register-int.h"
49 
50 #include <wsutil/crash_info.h>
51 #include <wsutil/epochs.h>
52 
53 /* Ptvcursor limits */
54 #define SUBTREE_ONCE_ALLOCATION_NUMBER 8
55 #define SUBTREE_MAX_LEVELS 256
56 
57 typedef struct __subtree_lvl {
58 	gint        cursor_offset;
59 	proto_item *it;
60 	proto_tree *tree;
61 } subtree_lvl;
62 
63 struct ptvcursor {
64 	wmem_allocator_t *scope;
65 	subtree_lvl *pushed_tree;
66 	guint8	     pushed_tree_index;
67 	guint8	     pushed_tree_max;
68 	proto_tree  *tree;
69 	tvbuff_t    *tvb;
70 	gint	     offset;
71 };
72 
73 #define cVALS(x) (const value_string*)(x)
74 
75 /** See inlined comments.
76  @param tree the tree to append this item to
77  @param free_block a code block to call to free resources if this returns
78  @return NULL if 'tree' is null */
79 #define CHECK_FOR_NULL_TREE_AND_FREE(tree, free_block)			\
80 	if (!tree) {							\
81 		free_block;						\
82 		return NULL;						\
83 	}
84 
85 /** See inlined comments.
86  @param tree the tree to append this item to
87  @param free_block a code block to call to free resources if this returns
88  @return NULL if 'tree' is null */
89 #define CHECK_FOR_NULL_TREE(tree) \
90 	CHECK_FOR_NULL_TREE_AND_FREE(tree, ((void)0))
91 
92 /** See inlined comments.
93  @param tree the tree to append this item to
94  @param hfindex field index
95  @param hfinfo header_field
96  @param free_block a code block to call to free resources if this returns
97  @return the header field matching 'hfinfo' */
98 #define TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, free_block) \
99 	/* If this item is not referenced we don't have to do much work	\
100 	   at all but we should still return a node so that field items	\
101 	   below this node (think proto_item_add_subtree()) will still	\
102 	   have somewhere to attach to or else filtering will not work	\
103 	   (they would be ignored since tree would be NULL).		\
104 	   DON'T try to fake a node where PTREE_FINFO(tree) is NULL	\
105 	   since dissectors that want to do proto_item_set_len() or	\
106 	   other operations that dereference this would crash.		\
107 	   We fake FT_PROTOCOL unless some clients have requested us	\
108 	   not to do so.						\
109 	*/								\
110 	PTREE_DATA(tree)->count++;					\
111 	PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);			\
112 	if (PTREE_DATA(tree)->count > prefs.gui_max_tree_items) {			\
113 		free_block;						\
114 		if (wireshark_abort_on_too_many_items) \
115 			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)", \
116 			    hfinfo->abbrev, prefs.gui_max_tree_items);	\
117 		/* Let the exception handler add items to the tree */	\
118 		PTREE_DATA(tree)->count = 0;				\
119 		THROW_MESSAGE(DissectorError,				\
120 			wmem_strdup_printf(PNODE_POOL(tree),		\
121 			    "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)", \
122 			    hfinfo->abbrev, prefs.gui_max_tree_items));	\
123 	}								\
124 	if (!(PTREE_DATA(tree)->visible)) {				\
125 		if (PTREE_FINFO(tree)) {				\
126 			if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT)	\
127 			    && (hfinfo->type != FT_PROTOCOL ||		\
128 				PTREE_DATA(tree)->fake_protocols)) {	\
129 				free_block;				\
130 				/* just return tree back to the caller */\
131 				return tree;				\
132 			}						\
133 		}							\
134 	}
135 
136 /** See inlined comments.
137  @param tree the tree to append this item to
138  @param hfindex field index
139  @param hfinfo header_field
140  @return the header field matching 'hfinfo' */
141 #define TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo) \
142 	TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, ((void)0))
143 
144 
145 /** See inlined comments.
146  @param pi the created protocol item we're about to return */
147 #define TRY_TO_FAKE_THIS_REPR(pi)	\
148 	ws_assert(pi);			\
149 	if (!(PTREE_DATA(pi)->visible)) { \
150 		/* If the tree (GUI) isn't visible it's pointless for us to generate the protocol \
151 		 * items string representation */ \
152 		return pi; \
153 	}
154 /* Same as above but returning void */
155 #define TRY_TO_FAKE_THIS_REPR_VOID(pi)	\
156 	if (!pi)			\
157 		return;			\
158 	if (!(PTREE_DATA(pi)->visible)) { \
159 		/* If the tree (GUI) isn't visible it's pointless for us to generate the protocol \
160 		 * items string representation */ \
161 		return; \
162 	}
163 /* Similar to above, but allows a NULL tree */
164 #define TRY_TO_FAKE_THIS_REPR_NESTED(pi)	\
165 	if ((pi == NULL) || (!(PTREE_DATA(pi)->visible))) { \
166 		/* If the tree (GUI) isn't visible it's pointless for us to generate the protocol \
167 		 * items string representation */ \
168 		return pi; \
169 	}
170 
171 #ifdef ENABLE_CHECK_FILTER
172 #define CHECK_HF_VALUE(type, modifier, start_values) \
173 { \
174 	const type *current; \
175 	int n, m; \
176 	current = start_values; \
177 	for (n=0; current; n++, current++) { \
178 		/* Drop out if we reached the end. */ \
179 		if ((current->value == 0) && (current->strptr == NULL)) { \
180 			break; \
181 		} \
182 		/* Check value against all previous */ \
183 		for (m=0; m < n; m++) { \
184 			/* There are lots of duplicates with the same string, \
185 			   so only report if different... */ \
186 			if ((start_values[m].value == current->value) && \
187 			    (strcmp(start_values[m].strptr, current->strptr) != 0)) { \
188 				ws_warning("Field '%s' (%s) has a conflicting entry in its" \
189 					  " value_string: %" modifier "u is at indices %u (%s) and %u (%s)", \
190 					  hfinfo->name, hfinfo->abbrev, \
191 					  current->value, m, start_values[m].strptr, n, current->strptr); \
192 			} \
193 		} \
194 	} \
195 }
196 #endif
197 
198 
199 static const char *hf_try_val_to_str(guint32 value, const header_field_info *hfinfo);
200 static const char *hf_try_val64_to_str(guint64 value, const header_field_info *hfinfo);
201 static int hfinfo_bitoffset(const header_field_info *hfinfo);
202 static int hfinfo_mask_bitwidth(const header_field_info *hfinfo);
203 static int hfinfo_container_bitwidth(const header_field_info *hfinfo);
204 
205 static void label_mark_truncated(char *label_str, gsize name_pos);
206 #define LABEL_MARK_TRUNCATED_START(label_str) label_mark_truncated(label_str, 0)
207 
208 static void fill_label_boolean(field_info *fi, gchar *label_str);
209 static void fill_label_bitfield_char(field_info *fi, gchar *label_str);
210 static void fill_label_bitfield(field_info *fi, gchar *label_str, gboolean is_signed);
211 static void fill_label_bitfield64(field_info *fi, gchar *label_str, gboolean is_signed);
212 static void fill_label_bitfield_varint(field_info *fi, gchar *label_str, gboolean is_signed);
213 static void fill_label_bitfield_varint64(field_info *fi, gchar *label_str, gboolean is_signed);
214 static void fill_label_char(field_info *fi, gchar *label_str);
215 static void fill_label_number(field_info *fi, gchar *label_str, gboolean is_signed);
216 static void fill_label_number64(field_info *fi, gchar *label_str, gboolean is_signed);
217 
218 static const char *hfinfo_char_value_format_display(int display, char buf[7], guint32 value);
219 static const char *hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[32], guint32 value);
220 static const char *hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[48], guint64 value);
221 static const char *hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value);
222 static const char *hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value);
223 static const char *hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[48], guint64 value);
224 static const char *hfinfo_number_value_format(const header_field_info *hfinfo, char buf[32], guint32 value);
225 static const char *hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[48], guint64 value);
226 static const char *hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], guint32 value);
227 static const char *hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[32], guint32 value);
228 static const char *hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[48], guint64 value);
229 
230 static void proto_cleanup_base(void);
231 
232 static proto_item *
233 proto_tree_add_node(proto_tree *tree, field_info *fi);
234 
235 static void
236 get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start, gint *length,
237 		gint *item_length, const guint encoding);
238 
239 static gint
240 get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start,
241 		gint length, guint item_length, const gint encoding);
242 
243 static field_info *
244 new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
245 	       const gint start, const gint item_length);
246 
247 static proto_item *
248 proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
249 		  gint start, gint *length);
250 
251 static void
252 proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap);
253 static void
254 proto_tree_set_representation(proto_item *pi, const char *format, va_list ap);
255 
256 static void
257 proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data);
258 static void
259 proto_tree_set_bytes(field_info *fi, const guint8* start_ptr, gint length);
260 static void
261 proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, gint offset, gint length);
262 static void
263 proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value);
264 static void
265 proto_tree_set_time(field_info *fi, const nstime_t *value_ptr);
266 static void
267 proto_tree_set_string(field_info *fi, const char* value);
268 static void
269 proto_tree_set_ax25(field_info *fi, const guint8* value);
270 static void
271 proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, gint start);
272 static void
273 proto_tree_set_vines(field_info *fi, const guint8* value);
274 static void
275 proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, gint start);
276 static void
277 proto_tree_set_ether(field_info *fi, const guint8* value);
278 static void
279 proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, gint start);
280 static void
281 proto_tree_set_ipxnet(field_info *fi, guint32 value);
282 static void
283 proto_tree_set_ipv4(field_info *fi, ws_in4_addr value);
284 static void
285 proto_tree_set_ipv6(field_info *fi, const guint8* value_ptr);
286 static void
287 proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
288 static void
289 proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
290 static void
291 proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr);
292 static void
293 proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, gint start, const guint encoding);
294 static void
295 proto_tree_set_oid(field_info *fi, const guint8* value_ptr, gint length);
296 static void
297 proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
298 static void
299 proto_tree_set_system_id(field_info *fi, const guint8* value_ptr, gint length);
300 static void
301 proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
302 static void
303 proto_tree_set_boolean(field_info *fi, guint64 value);
304 static void
305 proto_tree_set_float(field_info *fi, float value);
306 static void
307 proto_tree_set_double(field_info *fi, double value);
308 static void
309 proto_tree_set_uint(field_info *fi, guint32 value);
310 static void
311 proto_tree_set_int(field_info *fi, gint32 value);
312 static void
313 proto_tree_set_uint64(field_info *fi, guint64 value);
314 static void
315 proto_tree_set_int64(field_info *fi, gint64 value);
316 static void
317 proto_tree_set_eui64(field_info *fi, const guint64 value);
318 static void
319 proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, gint start, const guint encoding);
320 
321 /* Handle type length mismatch (now filterable) expert info */
322 static int proto_type_length_mismatch = -1;
323 static expert_field ei_type_length_mismatch_error = EI_INIT;
324 static expert_field ei_type_length_mismatch_warn = EI_INIT;
325 static void register_type_length_mismatch(void);
326 
327 /* Handle number string decoding errors with expert info */
328 static int proto_number_string_decoding_error = -1;
329 static expert_field ei_number_string_decoding_failed_error = EI_INIT;
330 static expert_field ei_number_string_decoding_erange_error = EI_INIT;
331 static void register_number_string_decodinws_error(void);
332 
333 /* Handle string errors expert info */
334 static int proto_string_errors = -1;
335 static expert_field ei_string_trailing_characters = EI_INIT;
336 static void register_string_errors(void);
337 
338 static int proto_register_field_init(header_field_info *hfinfo, const int parent);
339 
340 /* special-case header field used within proto.c */
341 static header_field_info hfi_text_only =
342 	{ "Text item",	"text", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL };
343 int hf_text_only = -1;
344 
345 /* Structure for information about a protocol */
346 struct _protocol {
347 	const char *name;               /* long description */
348 	const char *short_name;         /* short description */
349 	const char *filter_name;        /* name of this protocol in filters */
350 	GPtrArray  *fields;             /* fields for this protocol */
351 	int         proto_id;           /* field ID for this protocol */
352 	gboolean    is_enabled;         /* TRUE if protocol is enabled */
353 	gboolean    enabled_by_default; /* TRUE if protocol is enabled by default */
354 	gboolean    can_toggle;         /* TRUE if is_enabled can be changed */
355 	int         parent_proto_id;    /* Used to identify "pino"s (Protocol In Name Only).
356                                        For dissectors that need a protocol name so they
357                                        can be added to a dissector table, but use the
358                                        parent_proto_id for things like enable/disable */
359 	GList      *heur_list;          /* Heuristic dissectors associated with this protocol */
360 };
361 
362 /* List of all protocols */
363 static GList *protocols = NULL;
364 
365 /* Structure stored for deregistered g_slice */
366 struct g_slice_data {
367 	gsize    block_size;
368 	gpointer mem_block;
369 };
370 
371 /* Deregistered fields */
372 static GPtrArray *deregistered_fields = NULL;
373 static GPtrArray *deregistered_data = NULL;
374 static GPtrArray *deregistered_slice = NULL;
375 
376 /* indexed by prefix, contains initializers */
377 static GHashTable* prefixes = NULL;
378 
379 /* Contains information about a field when a dissector calls
380  * proto_tree_add_item.  */
381 #define FIELD_INFO_NEW(pool, fi)  fi = wmem_new(pool, field_info)
382 #define FIELD_INFO_FREE(pool, fi) wmem_free(pool, fi)
383 
384 /* Contains the space for proto_nodes. */
385 #define PROTO_NODE_INIT(node)			\
386 	node->first_child = NULL;		\
387 	node->last_child = NULL;		\
388 	node->next = NULL;
389 
390 #define PROTO_NODE_FREE(pool, node)			\
391 	wmem_free(pool, node)
392 
393 /* String space for protocol and field items for the GUI */
394 #define ITEM_LABEL_NEW(pool, il)			\
395 	il = wmem_new(pool, item_label_t);
396 #define ITEM_LABEL_FREE(pool, il)			\
397 	wmem_free(pool, il);
398 
399 #define PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)						\
400 	if((guint)hfindex >= gpa_hfinfo.len && wireshark_abort_on_dissector_bug)	\
401 		ws_error("Unregistered hf! index=%d", hfindex);					\
402 	DISSECTOR_ASSERT_HINT((guint)hfindex < gpa_hfinfo.len, "Unregistered hf!");	\
403 	DISSECTOR_ASSERT_HINT(gpa_hfinfo.hfi[hfindex] != NULL, "Unregistered hf!");	\
404 	hfinfo = gpa_hfinfo.hfi[hfindex];
405 
406 /* List which stores protocols and fields that have been registered */
407 typedef struct _gpa_hfinfo_t {
408 	guint32             len;
409 	guint32             allocated_len;
410 	header_field_info **hfi;
411 } gpa_hfinfo_t;
412 
413 static gpa_hfinfo_t gpa_hfinfo;
414 
415 /* Hash table of abbreviations and IDs */
416 static GHashTable *gpa_name_map = NULL;
417 static header_field_info *same_name_hfinfo;
418 
419 /* Hash table protocol aliases. const char * -> const char * */
420 static GHashTable *gpa_protocol_aliases = NULL;
421 
422 /*
423  * We're called repeatedly with the same field name when sorting a column.
424  * Cache our last gpa_name_map hit for faster lookups.
425  */
426 static char *last_field_name = NULL;
427 static header_field_info *last_hfinfo;
428 
save_same_name_hfinfo(gpointer data)429 static void save_same_name_hfinfo(gpointer data)
430 {
431 	same_name_hfinfo = (header_field_info*)data;
432 }
433 
434 /* Points to the first element of an array of bits, indexed by
435    a subtree item type; that array element is TRUE if subtrees of
436    an item of that type are to be expanded. */
437 static guint32 *tree_is_expanded;
438 
439 /* Number of elements in that array. */
440 int		num_tree_types;
441 
442 /* Name hashtables for fast detection of duplicate names */
443 static GHashTable* proto_names        = NULL;
444 static GHashTable* proto_short_names  = NULL;
445 static GHashTable* proto_filter_names = NULL;
446 
447 static gint
proto_compare_name(gconstpointer p1_arg,gconstpointer p2_arg)448 proto_compare_name(gconstpointer p1_arg, gconstpointer p2_arg)
449 {
450 	const protocol_t *p1 = (const protocol_t *)p1_arg;
451 	const protocol_t *p2 = (const protocol_t *)p2_arg;
452 
453 	return g_ascii_strcasecmp(p1->short_name, p2->short_name);
454 }
455 
456 static GSList *dissector_plugins = NULL;
457 
458 #ifdef HAVE_PLUGINS
459 void
proto_register_plugin(const proto_plugin * plug)460 proto_register_plugin(const proto_plugin *plug)
461 {
462 	dissector_plugins = g_slist_prepend(dissector_plugins, (proto_plugin *)plug);
463 }
464 #else /* HAVE_PLUGINS */
465 void
proto_register_plugin(const proto_plugin * plug _U_)466 proto_register_plugin(const proto_plugin *plug _U_)
467 {
468 	ws_warning("proto_register_plugin: built without support for binary plugins");
469 }
470 #endif /* HAVE_PLUGINS */
471 
472 static void
call_plugin_register_protoinfo(gpointer data,gpointer user_data _U_)473 call_plugin_register_protoinfo(gpointer data, gpointer user_data _U_)
474 {
475 	proto_plugin *plug = (proto_plugin *)data;
476 
477 	if (plug->register_protoinfo) {
478 		plug->register_protoinfo();
479 	}
480 }
481 
482 static void
call_plugin_register_handoff(gpointer data,gpointer user_data _U_)483 call_plugin_register_handoff(gpointer data, gpointer user_data _U_)
484 {
485 	proto_plugin *plug = (proto_plugin *)data;
486 
487 	if (plug->register_handoff) {
488 		plug->register_handoff();
489 	}
490 }
491 
492 /* initialize data structures and register protocols and fields */
493 void
proto_init(GSList * register_all_plugin_protocols_list,GSList * register_all_plugin_handoffs_list,register_cb cb,gpointer client_data)494 proto_init(GSList *register_all_plugin_protocols_list,
495 	   GSList *register_all_plugin_handoffs_list,
496 	   register_cb cb,
497 	   gpointer client_data)
498 {
499 	proto_cleanup_base();
500 
501 	proto_names        = g_hash_table_new(g_str_hash, g_str_equal);
502 	proto_short_names  = g_hash_table_new(g_str_hash, g_str_equal);
503 	proto_filter_names = g_hash_table_new(g_str_hash, g_str_equal);
504 
505 	gpa_hfinfo.len           = 0;
506 	gpa_hfinfo.allocated_len = 0;
507 	gpa_hfinfo.hfi           = NULL;
508 	gpa_name_map             = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, save_same_name_hfinfo);
509 	gpa_protocol_aliases     = g_hash_table_new(g_str_hash, g_str_equal);
510 	deregistered_fields      = g_ptr_array_new();
511 	deregistered_data        = g_ptr_array_new();
512 	deregistered_slice       = g_ptr_array_new();
513 
514 	/* Initialize the ftype subsystem */
515 	ftypes_initialize();
516 
517 	/* Initialize the addres type subsystem */
518 	address_types_initialize();
519 
520 	/* Register one special-case FT_TEXT_ONLY field for use when
521 	   converting wireshark to new-style proto_tree. These fields
522 	   are merely strings on the GUI tree; they are not filterable */
523 	hf_text_only = proto_register_field_init(&hfi_text_only, -1);
524 
525 	/* Register the pseudo-protocols used for exceptions. */
526 	register_show_exception();
527 	register_type_length_mismatch();
528 	register_number_string_decodinws_error();
529 	register_string_errors();
530 
531 	/* Have each built-in dissector register its protocols, fields,
532 	   dissector tables, and dissectors to be called through a
533 	   handle, and do whatever one-time initialization it needs to
534 	   do. */
535 	register_all_protocols(cb, client_data);
536 
537 	/* Now call the registration routines for all epan plugins. */
538 	for (GSList *l = register_all_plugin_protocols_list; l != NULL; l = l->next) {
539 		((void (*)(register_cb, gpointer))l->data)(cb, client_data);
540 	}
541 
542 	/* Now call the registration routines for all dissector plugins. */
543 	if (cb)
544 		(*cb)(RA_PLUGIN_REGISTER, NULL, client_data);
545 	g_slist_foreach(dissector_plugins, call_plugin_register_protoinfo, NULL);
546 
547 	/* Now call the "handoff registration" routines of all built-in
548 	   dissectors; those routines register the dissector in other
549 	   dissectors' handoff tables, and fetch any dissector handles
550 	   they need. */
551 	register_all_protocol_handoffs(cb, client_data);
552 
553 	/* Now do the same with epan plugins. */
554 	for (GSList *l = register_all_plugin_handoffs_list; l != NULL; l = l->next) {
555 		((void (*)(register_cb, gpointer))l->data)(cb, client_data);
556 	}
557 
558 	/* Now do the same with dissector plugins. */
559 	if (cb)
560 		(*cb)(RA_PLUGIN_HANDOFF, NULL, client_data);
561 	g_slist_foreach(dissector_plugins, call_plugin_register_handoff, NULL);
562 
563 	/* sort the protocols by protocol name */
564 	protocols = g_list_sort(protocols, proto_compare_name);
565 
566 	/* We've assigned all the subtree type values; allocate the array
567 	   for them, and zero it out. */
568 	tree_is_expanded = g_new0(guint32, (num_tree_types/32)+1);
569 }
570 
571 static void
proto_cleanup_base(void)572 proto_cleanup_base(void)
573 {
574 	protocol_t *protocol;
575 	header_field_info *hfinfo;
576 
577 	/* Free the abbrev/ID hash table */
578 	if (gpa_name_map) {
579 		g_hash_table_destroy(gpa_name_map);
580 		gpa_name_map = NULL;
581 	}
582 	if (gpa_protocol_aliases) {
583 		g_hash_table_destroy(gpa_protocol_aliases);
584 		gpa_protocol_aliases = NULL;
585 	}
586 	g_free(last_field_name);
587 	last_field_name = NULL;
588 
589 	while (protocols) {
590 		protocol = (protocol_t *)protocols->data;
591 		PROTO_REGISTRAR_GET_NTH(protocol->proto_id, hfinfo);
592 		DISSECTOR_ASSERT(protocol->proto_id == hfinfo->id);
593 
594 		g_slice_free(header_field_info, hfinfo);
595 		if (protocol->parent_proto_id != -1) {
596 			// pino protocol
597 			DISSECTOR_ASSERT(protocol->fields == NULL); //helpers should not have any registered fields
598 			DISSECTOR_ASSERT(protocol->heur_list == NULL); //helpers should not have a heuristic list
599 		} else {
600 			if (protocol->fields) {
601 				g_ptr_array_free(protocol->fields, TRUE);
602 			}
603 			g_list_free(protocol->heur_list);
604 		}
605 		protocols = g_list_remove(protocols, protocol);
606 		g_free(protocol);
607 	}
608 
609 	if (proto_names) {
610 		g_hash_table_destroy(proto_names);
611 		proto_names = NULL;
612 	}
613 
614 	if (proto_short_names) {
615 		g_hash_table_destroy(proto_short_names);
616 		proto_short_names = NULL;
617 	}
618 
619 	if (proto_filter_names) {
620 		g_hash_table_destroy(proto_filter_names);
621 		proto_filter_names = NULL;
622 	}
623 
624 	if (gpa_hfinfo.allocated_len) {
625 		gpa_hfinfo.len           = 0;
626 		gpa_hfinfo.allocated_len = 0;
627 		g_free(gpa_hfinfo.hfi);
628 		gpa_hfinfo.hfi           = NULL;
629 	}
630 
631 	if (deregistered_fields) {
632 		g_ptr_array_free(deregistered_fields, TRUE);
633 		deregistered_fields = NULL;
634 	}
635 
636 	if (deregistered_data) {
637 		g_ptr_array_free(deregistered_data, TRUE);
638 		deregistered_data = NULL;
639 	}
640 
641 	if (deregistered_slice) {
642 		g_ptr_array_free(deregistered_slice, TRUE);
643 		deregistered_slice = NULL;
644 	}
645 
646 	g_free(tree_is_expanded);
647 	tree_is_expanded = NULL;
648 
649 	if (prefixes)
650 		g_hash_table_destroy(prefixes);
651 }
652 
653 void
proto_cleanup(void)654 proto_cleanup(void)
655 {
656 	proto_free_deregistered_fields();
657 	proto_cleanup_base();
658 
659 	g_slist_free(dissector_plugins);
660 	dissector_plugins = NULL;
661 }
662 
663 static gboolean
proto_tree_traverse_pre_order(proto_tree * tree,proto_tree_traverse_func func,gpointer data)664 proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
665 			      gpointer data)
666 {
667 	proto_node *pnode = tree;
668 	proto_node *child;
669 	proto_node *current;
670 
671 	if (func(pnode, data))
672 		return TRUE;
673 
674 	child = pnode->first_child;
675 	while (child != NULL) {
676 		/*
677 		 * The routine we call might modify the child, e.g. by
678 		 * freeing it, so we get the child's successor before
679 		 * calling that routine.
680 		 */
681 		current = child;
682 		child   = current->next;
683 		if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
684 			return TRUE;
685 	}
686 
687 	return FALSE;
688 }
689 
690 gboolean
proto_tree_traverse_post_order(proto_tree * tree,proto_tree_traverse_func func,gpointer data)691 proto_tree_traverse_post_order(proto_tree *tree, proto_tree_traverse_func func,
692 			       gpointer data)
693 {
694 	proto_node *pnode = tree;
695 	proto_node *child;
696 	proto_node *current;
697 
698 	child = pnode->first_child;
699 	while (child != NULL) {
700 		/*
701 		 * The routine we call might modify the child, e.g. by
702 		 * freeing it, so we get the child's successor before
703 		 * calling that routine.
704 		 */
705 		current = child;
706 		child   = current->next;
707 		if (proto_tree_traverse_post_order((proto_tree *)current, func, data))
708 			return TRUE;
709 	}
710 	if (func(pnode, data))
711 		return TRUE;
712 
713 	return FALSE;
714 }
715 
716 void
proto_tree_children_foreach(proto_tree * tree,proto_tree_foreach_func func,gpointer data)717 proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
718 			    gpointer data)
719 {
720 	proto_node *node = tree;
721 	proto_node *current;
722 
723 	if (!node)
724 		return;
725 
726 	node = node->first_child;
727 	while (node != NULL) {
728 		current = node;
729 		node    = current->next;
730 		func((proto_tree *)current, data);
731 	}
732 }
733 
734 static void
free_GPtrArray_value(gpointer key,gpointer value,gpointer user_data _U_)735 free_GPtrArray_value(gpointer key, gpointer value, gpointer user_data _U_)
736 {
737 	GPtrArray         *ptrs = (GPtrArray *)value;
738 	gint               hfid = GPOINTER_TO_UINT(key);
739 	header_field_info *hfinfo;
740 
741 	PROTO_REGISTRAR_GET_NTH(hfid, hfinfo);
742 	if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
743 		/* when a field is referenced by a filter this also
744 		   affects the refcount for the parent protocol so we need
745 		   to adjust the refcount for the parent as well
746 		*/
747 		if (hfinfo->parent != -1) {
748 			header_field_info *parent_hfinfo;
749 			PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
750 			parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
751 		}
752 		hfinfo->ref_type = HF_REF_TYPE_NONE;
753 	}
754 
755 	g_ptr_array_free(ptrs, TRUE);
756 }
757 
758 static void
proto_tree_free_node(proto_node * node,gpointer data _U_)759 proto_tree_free_node(proto_node *node, gpointer data _U_)
760 {
761 	field_info *finfo  = PNODE_FINFO(node);
762 
763 	proto_tree_children_foreach(node, proto_tree_free_node, NULL);
764 
765 	FVALUE_CLEANUP(&finfo->value);
766 }
767 
768 void
proto_tree_reset(proto_tree * tree)769 proto_tree_reset(proto_tree *tree)
770 {
771 	tree_data_t *tree_data = PTREE_DATA(tree);
772 
773 	proto_tree_children_foreach(tree, proto_tree_free_node, NULL);
774 
775 	/* free tree data */
776 	if (tree_data->interesting_hfids) {
777 		/* Free all the GPtrArray's in the interesting_hfids hash. */
778 		g_hash_table_foreach(tree_data->interesting_hfids,
779 			free_GPtrArray_value, NULL);
780 
781 		/* And then remove all values. */
782 		g_hash_table_remove_all(tree_data->interesting_hfids);
783 	}
784 
785 	/* Reset track of the number of children */
786 	tree_data->count = 0;
787 
788 	PROTO_NODE_INIT(tree);
789 }
790 
791 /* frees the resources that the dissection a proto_tree uses */
792 void
proto_tree_free(proto_tree * tree)793 proto_tree_free(proto_tree *tree)
794 {
795 	tree_data_t *tree_data = PTREE_DATA(tree);
796 
797 	proto_tree_children_foreach(tree, proto_tree_free_node, NULL);
798 
799 	/* free tree data */
800 	if (tree_data->interesting_hfids) {
801 		/* Free all the GPtrArray's in the interesting_hfids hash. */
802 		g_hash_table_foreach(tree_data->interesting_hfids,
803 			free_GPtrArray_value, NULL);
804 
805 		/* And then destroy the hash. */
806 		g_hash_table_destroy(tree_data->interesting_hfids);
807 	}
808 
809 	g_slice_free(tree_data_t, tree_data);
810 
811 	g_slice_free(proto_tree, tree);
812 }
813 
814 /* Is the parsing being done for a visible proto_tree or an invisible one?
815  * By setting this correctly, the proto_tree creation is sped up by not
816  * having to call g_vsnprintf and copy strings around.
817  */
818 gboolean
proto_tree_set_visible(proto_tree * tree,gboolean visible)819 proto_tree_set_visible(proto_tree *tree, gboolean visible)
820 {
821 	gboolean old_visible = PTREE_DATA(tree)->visible;
822 
823 	PTREE_DATA(tree)->visible = visible;
824 
825 	return old_visible;
826 }
827 
828 void
proto_tree_set_fake_protocols(proto_tree * tree,gboolean fake_protocols)829 proto_tree_set_fake_protocols(proto_tree *tree, gboolean fake_protocols)
830 {
831 	PTREE_DATA(tree)->fake_protocols = fake_protocols;
832 }
833 
834 /* Assume dissector set only its protocol fields.
835    This function is called by dissectors and allows the speeding up of filtering
836    in wireshark; if this function returns FALSE it is safe to reset tree to NULL
837    and thus skip calling most of the expensive proto_tree_add_...()
838    functions.
839    If the tree is visible we implicitly assume the field is referenced.
840 */
841 gboolean
proto_field_is_referenced(proto_tree * tree,int proto_id)842 proto_field_is_referenced(proto_tree *tree, int proto_id)
843 {
844 	register header_field_info *hfinfo;
845 
846 
847 	if (!tree)
848 		return FALSE;
849 
850 	if (PTREE_DATA(tree)->visible)
851 		return TRUE;
852 
853 	PROTO_REGISTRAR_GET_NTH(proto_id, hfinfo);
854 	if (hfinfo->ref_type != HF_REF_TYPE_NONE)
855 		return TRUE;
856 
857 	if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)->fake_protocols)
858 		return TRUE;
859 
860 	return FALSE;
861 }
862 
863 
864 /* Finds a record in the hfinfo array by id. */
865 header_field_info *
proto_registrar_get_nth(guint hfindex)866 proto_registrar_get_nth(guint hfindex)
867 {
868 	register header_field_info *hfinfo;
869 
870 	PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
871 	return hfinfo;
872 }
873 
874 
875 /*	Prefix initialization
876  *	  this allows for a dissector to register a display filter name prefix
877  *	  so that it can delay the initialization of the hf array as long as
878  *	  possible.
879  */
880 
881 /* compute a hash for the part before the dot of a display filter */
882 static guint
prefix_hash(gconstpointer key)883 prefix_hash (gconstpointer key) {
884 	/* end the string at the dot and compute its hash */
885 	gchar* copy = g_strdup((const gchar *)key);
886 	gchar* c    = copy;
887 	guint tmp;
888 
889 	for (; *c; c++) {
890 		if (*c == '.') {
891 			*c = 0;
892 			break;
893 		}
894 	}
895 
896 	tmp = g_str_hash(copy);
897 	g_free(copy);
898 	return tmp;
899 }
900 
901 /* are both strings equal up to the end or the dot? */
902 static gboolean
prefix_equal(gconstpointer ap,gconstpointer bp)903 prefix_equal (gconstpointer ap, gconstpointer bp) {
904 	const gchar* a = (const gchar *)ap;
905 	const gchar* b = (const gchar *)bp;
906 
907 	do {
908 		gchar ac = *a++;
909 		gchar bc = *b++;
910 
911 		if ( (ac == '.' || ac == '\0') &&   (bc == '.' || bc == '\0') ) return TRUE;
912 
913 		if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE;
914 		if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE;
915 
916 		if (ac != bc) return FALSE;
917 	} while (1);
918 
919 	return FALSE;
920 }
921 
922 /* Register a new prefix for "delayed" initialization of field arrays */
923 void
proto_register_prefix(const char * prefix,prefix_initializer_t pi)924 proto_register_prefix(const char *prefix, prefix_initializer_t pi ) {
925 	if (! prefixes ) {
926 		prefixes = g_hash_table_new(prefix_hash, prefix_equal);
927 	}
928 
929 	g_hash_table_insert(prefixes, (gpointer)prefix, (gpointer)pi);
930 }
931 
932 /* helper to call all prefix initializers */
933 static gboolean
initialize_prefix(gpointer k,gpointer v,gpointer u _U_)934 initialize_prefix(gpointer k, gpointer v, gpointer u _U_) {
935 	((prefix_initializer_t)v)((const char *)k);
936 	return TRUE;
937 }
938 
939 /** Initialize every remaining uninitialized prefix. */
940 void
proto_initialize_all_prefixes(void)941 proto_initialize_all_prefixes(void) {
942 	g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL);
943 }
944 
945 /* Finds a record in the hfinfo array by name.
946  * If it fails to find it in the already registered fields,
947  * it tries to find and call an initializer in the prefixes
948  * table and if so it looks again.
949  */
950 
951 header_field_info *
proto_registrar_get_byname(const char * field_name)952 proto_registrar_get_byname(const char *field_name)
953 {
954 	header_field_info    *hfinfo;
955 	prefix_initializer_t  pi;
956 
957 	if (!field_name)
958 		return NULL;
959 
960 	if (g_strcmp0(field_name, last_field_name) == 0) {
961 		return last_hfinfo;
962 	}
963 
964 	hfinfo = (header_field_info *)g_hash_table_lookup(gpa_name_map, field_name);
965 
966 	if (hfinfo) {
967 		g_free(last_field_name);
968 		last_field_name = g_strdup(field_name);
969 		last_hfinfo = hfinfo;
970 		return hfinfo;
971 	}
972 
973 	if (!prefixes)
974 		return NULL;
975 
976 	if ((pi = (prefix_initializer_t)g_hash_table_lookup(prefixes, field_name) ) != NULL) {
977 		pi(field_name);
978 		g_hash_table_remove(prefixes, field_name);
979 	} else {
980 		return NULL;
981 	}
982 
983 	hfinfo = (header_field_info *)g_hash_table_lookup(gpa_name_map, field_name);
984 
985 	if (hfinfo) {
986 		g_free(last_field_name);
987 		last_field_name = g_strdup(field_name);
988 		last_hfinfo = hfinfo;
989 	}
990 	return hfinfo;
991 }
992 
993 header_field_info*
proto_registrar_get_byalias(const char * alias_name)994 proto_registrar_get_byalias(const char *alias_name)
995 {
996 	if (!alias_name) {
997 		return NULL;
998 	}
999 
1000 	/* Find our aliased protocol. */
1001 	char *an_copy = g_strdup(alias_name);
1002 	char *dot = strchr(an_copy, '.');
1003 	if (dot) {
1004 		*dot = '\0';
1005 	}
1006 	const char *proto_pfx = (const char *) g_hash_table_lookup(gpa_protocol_aliases, an_copy);
1007 	if (!proto_pfx) {
1008 		g_free(an_copy);
1009 		return NULL;
1010 	}
1011 
1012 	/* Construct our aliased field and look it up. */
1013 	GString *filter_name = g_string_new(proto_pfx);
1014 	if (dot) {
1015 		g_string_append_printf(filter_name, ".%s", dot+1);
1016 	}
1017 	header_field_info *hfinfo = proto_registrar_get_byname(filter_name->str);
1018 	g_free(an_copy);
1019 	g_string_free(filter_name, TRUE);
1020 
1021 	return hfinfo;
1022 }
1023 
1024 int
proto_registrar_get_id_byname(const char * field_name)1025 proto_registrar_get_id_byname(const char *field_name)
1026 {
1027 	header_field_info *hfinfo;
1028 
1029 	hfinfo = proto_registrar_get_byname(field_name);
1030 
1031 	if (!hfinfo)
1032 		return -1;
1033 
1034 	return hfinfo->id;
1035 }
1036 
1037 
1038 static char *
hfinfo_format_text(wmem_allocator_t * scope,const header_field_info * hfinfo,const guchar * string)1039 hfinfo_format_text(wmem_allocator_t *scope, const header_field_info *hfinfo,
1040     const guchar *string)
1041 {
1042 	switch (hfinfo->display) {
1043 		case STR_ASCII:
1044 			return format_text(scope, string, strlen(string));
1045 /*
1046 		case STR_ASCII_WSP
1047 			return format_text_wsp(string, strlen(string));
1048  */
1049 		case STR_UNICODE:
1050 			return format_text(scope, string, strlen(string));
1051 	}
1052 
1053 	return format_text(scope, string, strlen(string));
1054 }
1055 
1056 static char *
hfinfo_format_bytes(wmem_allocator_t * scope,const header_field_info * hfinfo,const guint8 * bytes,guint length)1057 hfinfo_format_bytes(wmem_allocator_t *scope, const header_field_info *hfinfo,
1058     const guint8 *bytes, guint length)
1059 {
1060 	char *str = NULL;
1061 	const guint8 *p;
1062 	gboolean is_printable;
1063 
1064 	if (bytes) {
1065 		if (hfinfo->display & BASE_SHOW_ASCII_PRINTABLE) {
1066 			/*
1067 			 * Check whether all bytes are printable.
1068 			 */
1069 			is_printable = TRUE;
1070 			for (p = bytes; p < bytes+length; p++) {
1071 				if (!g_ascii_isprint(*p)) {
1072 					/* Not printable. */
1073 					is_printable = FALSE;
1074 					break;
1075 				}
1076 			}
1077 
1078 			/*
1079 			 * If all bytes are printable ASCII, show the bytes
1080 			 * as a string - in quotes to indicate that it's
1081 			 * a string.
1082 			 */
1083 			if (is_printable) {
1084 				str = wmem_strdup_printf(scope, "\"%.*s\"",
1085 				    (int)length, bytes);
1086 				return str;
1087 			}
1088 		}
1089 
1090 		/*
1091 		 * Either it's not printable ASCII, or we don't care whether
1092 		 * it's printable ASCII; show it as hex bytes.
1093 		 */
1094 		switch (FIELD_DISPLAY(hfinfo->display)) {
1095 		case SEP_DOT:
1096 			str = bytes_to_str_punct(scope, bytes, length, '.');
1097 			break;
1098 		case SEP_DASH:
1099 			str = bytes_to_str_punct(scope, bytes, length, '-');
1100 			break;
1101 		case SEP_COLON:
1102 			str = bytes_to_str_punct(scope, bytes, length, ':');
1103 			break;
1104 		case SEP_SPACE:
1105 			str = bytes_to_str_punct(scope, bytes, length, ' ');
1106 			break;
1107 		case BASE_NONE:
1108 		default:
1109 			if (prefs.display_byte_fields_with_spaces) {
1110 				str = bytes_to_str_punct(scope, bytes, length, ' ');
1111 			} else {
1112 				str = bytes_to_str(scope, bytes, length);
1113 			}
1114 			break;
1115 		}
1116 	}
1117 	else {
1118 		if (hfinfo->display & BASE_ALLOW_ZERO) {
1119 			str = wmem_strdup(scope, "<none>");
1120 		} else {
1121 			str = wmem_strdup(scope, "<MISSING>");
1122 		}
1123 	}
1124 	return str;
1125 }
1126 
1127 static void
ptvcursor_new_subtree_levels(ptvcursor_t * ptvc)1128 ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
1129 {
1130 	subtree_lvl *pushed_tree;
1131 
1132 	DISSECTOR_ASSERT(ptvc->pushed_tree_max <= SUBTREE_MAX_LEVELS-SUBTREE_ONCE_ALLOCATION_NUMBER);
1133 	ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER;
1134 
1135 	pushed_tree = (subtree_lvl *)wmem_realloc(ptvc->scope, (void *)ptvc->pushed_tree, sizeof(subtree_lvl) * ptvc->pushed_tree_max);
1136 	DISSECTOR_ASSERT(pushed_tree != NULL);
1137 	ptvc->pushed_tree = pushed_tree;
1138 }
1139 
1140 static void
ptvcursor_free_subtree_levels(ptvcursor_t * ptvc)1141 ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
1142 {
1143 	ptvc->pushed_tree       = NULL;
1144 	ptvc->pushed_tree_max   = 0;
1145 	DISSECTOR_ASSERT(ptvc->pushed_tree_index == 0);
1146 	ptvc->pushed_tree_index = 0;
1147 }
1148 
1149 /* Allocates an initializes a ptvcursor_t with 3 variables:
1150  *	proto_tree, tvbuff, and offset. */
1151 ptvcursor_t *
ptvcursor_new(wmem_allocator_t * scope,proto_tree * tree,tvbuff_t * tvb,gint offset)1152 ptvcursor_new(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb, gint offset)
1153 {
1154 	ptvcursor_t *ptvc;
1155 
1156 	ptvc                    = wmem_new(scope, ptvcursor_t);
1157 	ptvc->scope             = scope;
1158 	ptvc->tree              = tree;
1159 	ptvc->tvb               = tvb;
1160 	ptvc->offset            = offset;
1161 	ptvc->pushed_tree       = NULL;
1162 	ptvc->pushed_tree_max   = 0;
1163 	ptvc->pushed_tree_index = 0;
1164 	return ptvc;
1165 }
1166 
1167 
1168 /* Frees memory for ptvcursor_t, but nothing deeper than that. */
1169 void
ptvcursor_free(ptvcursor_t * ptvc)1170 ptvcursor_free(ptvcursor_t *ptvc)
1171 {
1172 	ptvcursor_free_subtree_levels(ptvc);
1173 	/*g_free(ptvc);*/
1174 }
1175 
1176 /* Returns tvbuff. */
1177 tvbuff_t *
ptvcursor_tvbuff(ptvcursor_t * ptvc)1178 ptvcursor_tvbuff(ptvcursor_t *ptvc)
1179 {
1180 	return ptvc->tvb;
1181 }
1182 
1183 /* Returns current offset. */
1184 gint
ptvcursor_current_offset(ptvcursor_t * ptvc)1185 ptvcursor_current_offset(ptvcursor_t *ptvc)
1186 {
1187 	return ptvc->offset;
1188 }
1189 
1190 proto_tree *
ptvcursor_tree(ptvcursor_t * ptvc)1191 ptvcursor_tree(ptvcursor_t *ptvc)
1192 {
1193 	if (!ptvc)
1194 		return NULL;
1195 
1196 	return ptvc->tree;
1197 }
1198 
1199 void
ptvcursor_set_tree(ptvcursor_t * ptvc,proto_tree * tree)1200 ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
1201 {
1202 	ptvc->tree = tree;
1203 }
1204 
1205 /* creates a subtree, sets it as the working tree and pushes the old working tree */
1206 proto_tree *
ptvcursor_push_subtree(ptvcursor_t * ptvc,proto_item * it,gint ett_subtree)1207 ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree)
1208 {
1209 	subtree_lvl *subtree;
1210 	if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
1211 		ptvcursor_new_subtree_levels(ptvc);
1212 
1213 	subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1214 	subtree->tree = ptvc->tree;
1215 	subtree->it= NULL;
1216 	ptvc->pushed_tree_index++;
1217 	return ptvcursor_set_subtree(ptvc, it, ett_subtree);
1218 }
1219 
1220 /* pops a subtree */
1221 void
ptvcursor_pop_subtree(ptvcursor_t * ptvc)1222 ptvcursor_pop_subtree(ptvcursor_t *ptvc)
1223 {
1224 	subtree_lvl *subtree;
1225 
1226 	if (ptvc->pushed_tree_index <= 0)
1227 		return;
1228 
1229 	ptvc->pushed_tree_index--;
1230 	subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1231 	if (subtree->it != NULL)
1232 		proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
1233 
1234 	ptvc->tree = subtree->tree;
1235 }
1236 
1237 /* saves the current tvb offset and the item in the current subtree level */
1238 static void
ptvcursor_subtree_set_item(ptvcursor_t * ptvc,proto_item * it)1239 ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
1240 {
1241 	subtree_lvl *subtree;
1242 
1243 	DISSECTOR_ASSERT(ptvc->pushed_tree_index > 0);
1244 
1245 	subtree                = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
1246 	subtree->it            = it;
1247 	subtree->cursor_offset = ptvcursor_current_offset(ptvc);
1248 }
1249 
1250 /* Creates a subtree and adds it to the cursor as the working tree but does not
1251  * save the old working tree */
1252 proto_tree *
ptvcursor_set_subtree(ptvcursor_t * ptvc,proto_item * it,gint ett_subtree)1253 ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree)
1254 {
1255 	ptvc->tree = proto_item_add_subtree(it, ett_subtree);
1256 	return ptvc->tree;
1257 }
1258 
1259 static proto_tree *
ptvcursor_add_subtree_item(ptvcursor_t * ptvc,proto_item * it,gint ett_subtree,gint length)1260 ptvcursor_add_subtree_item(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree, gint length)
1261 {
1262 	ptvcursor_push_subtree(ptvc, it, ett_subtree);
1263 	if (length == SUBTREE_UNDEFINED_LENGTH)
1264 		ptvcursor_subtree_set_item(ptvc, it);
1265 	return ptvcursor_tree(ptvc);
1266 }
1267 
1268 /* Add an item to the tree and create a subtree
1269  * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1270  * In this case, when the subtree will be closed, the parent item length will
1271  * be equal to the advancement of the cursor since the creation of the subtree.
1272  */
1273 proto_tree *
ptvcursor_add_with_subtree(ptvcursor_t * ptvc,int hfindex,gint length,const guint encoding,gint ett_subtree)1274 ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, gint length,
1275 			   const guint encoding, gint ett_subtree)
1276 {
1277 	proto_item *it;
1278 
1279 	it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
1280 	return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
1281 }
1282 
1283 static proto_item *
1284 proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, gint start, gint length);
1285 
1286 /* Add a text node to the tree and create a subtree
1287  * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1288  * In this case, when the subtree will be closed, the item length will be equal
1289  * to the advancement of the cursor since the creation of the subtree.
1290  */
1291 proto_tree *
ptvcursor_add_text_with_subtree(ptvcursor_t * ptvc,gint length,gint ett_subtree,const char * format,...)1292 ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, gint length,
1293 				gint ett_subtree, const char *format, ...)
1294 {
1295 	proto_item        *pi;
1296 	va_list            ap;
1297 	header_field_info *hfinfo;
1298 	proto_tree        *tree;
1299 
1300 	tree = ptvcursor_tree(ptvc);
1301 
1302 	CHECK_FOR_NULL_TREE(tree);
1303 
1304 	TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1305 
1306 	pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
1307 				      ptvcursor_current_offset(ptvc), length);
1308 
1309 	TRY_TO_FAKE_THIS_REPR(pi);
1310 
1311 	va_start(ap, format);
1312 	proto_tree_set_representation(pi, format, ap);
1313 	va_end(ap);
1314 
1315 	return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
1316 }
1317 
1318 /* Add a text-only node, leaving it to our caller to fill the text in */
1319 static proto_item *
proto_tree_add_text_node(proto_tree * tree,tvbuff_t * tvb,gint start,gint length)1320 proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, gint start, gint length)
1321 {
1322 	proto_item *pi;
1323 
1324 	if (tree == NULL)
1325 		return NULL;
1326 
1327 	pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
1328 
1329 	return pi;
1330 }
1331 
1332 /* (INTERNAL USE ONLY) Add a text-only node to the proto_tree */
1333 proto_item *
proto_tree_add_text_internal(proto_tree * tree,tvbuff_t * tvb,gint start,gint length,const char * format,...)1334 proto_tree_add_text_internal(proto_tree *tree, tvbuff_t *tvb, gint start, gint length,
1335 		    const char *format, ...)
1336 {
1337 	proto_item	  *pi;
1338 	va_list		   ap;
1339 	header_field_info *hfinfo;
1340 
1341 	if (length == -1) {
1342 		length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
1343 	} else {
1344 		tvb_ensure_bytes_exist(tvb, start, length);
1345 	}
1346 
1347 	CHECK_FOR_NULL_TREE(tree);
1348 
1349 	TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1350 
1351 	pi = proto_tree_add_text_node(tree, tvb, start, length);
1352 
1353 	TRY_TO_FAKE_THIS_REPR(pi);
1354 
1355 	va_start(ap, format);
1356 	proto_tree_set_representation(pi, format, ap);
1357 	va_end(ap);
1358 
1359 	return pi;
1360 }
1361 
1362 /* (INTERNAL USE ONLY) Add a text-only node to the proto_tree (va_list version) */
1363 proto_item *
proto_tree_add_text_valist_internal(proto_tree * tree,tvbuff_t * tvb,gint start,gint length,const char * format,va_list ap)1364 proto_tree_add_text_valist_internal(proto_tree *tree, tvbuff_t *tvb, gint start,
1365 			   gint length, const char *format, va_list ap)
1366 {
1367 	proto_item        *pi;
1368 	header_field_info *hfinfo;
1369 
1370 	if (length == -1) {
1371 		length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
1372 	} else {
1373 		tvb_ensure_bytes_exist(tvb, start, length);
1374 	}
1375 
1376 	CHECK_FOR_NULL_TREE(tree);
1377 
1378 	TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1379 
1380 	pi = proto_tree_add_text_node(tree, tvb, start, length);
1381 
1382 	TRY_TO_FAKE_THIS_REPR(pi);
1383 
1384 	proto_tree_set_representation(pi, format, ap);
1385 
1386 	return pi;
1387 }
1388 
1389 /* Add a text-only node that creates a subtree underneath.
1390  */
1391 proto_tree *
proto_tree_add_subtree(proto_tree * tree,tvbuff_t * tvb,gint start,gint length,gint idx,proto_item ** tree_item,const char * text)1392 proto_tree_add_subtree(proto_tree *tree, tvbuff_t *tvb, gint start, gint length, gint idx, proto_item **tree_item, const char *text)
1393 {
1394 	return proto_tree_add_subtree_format(tree, tvb, start, length, idx, tree_item, "%s", text);
1395 }
1396 
1397 /* Add a text-only node that creates a subtree underneath.
1398  */
1399 proto_tree *
proto_tree_add_subtree_format(proto_tree * tree,tvbuff_t * tvb,gint start,gint length,gint idx,proto_item ** tree_item,const char * format,...)1400 proto_tree_add_subtree_format(proto_tree *tree, tvbuff_t *tvb, gint start, gint length, gint idx, proto_item **tree_item, const char *format, ...)
1401 {
1402 	proto_tree *pt;
1403 	proto_item *pi;
1404 	va_list	    ap;
1405 
1406 	va_start(ap, format);
1407 	pi = proto_tree_add_text_valist_internal(tree, tvb, start, length, format, ap);
1408 	va_end(ap);
1409 
1410 	if (tree_item != NULL)
1411 		*tree_item = pi;
1412 
1413 	pt = proto_item_add_subtree(pi, idx);
1414 
1415 	return pt;
1416 }
1417 
1418 /* Add a text-only node for debugging purposes. The caller doesn't need
1419  * to worry about tvbuff, start, or length. Debug message gets sent to
1420  * STDOUT, too */
1421 proto_item *
proto_tree_add_debug_text(proto_tree * tree,const char * format,...)1422 proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
1423 {
1424 	proto_item *pi;
1425 	va_list	    ap;
1426 
1427 	pi = proto_tree_add_text_node(tree, NULL, 0, 0);
1428 
1429 	if (pi) {
1430 		va_start(ap, format);
1431 		proto_tree_set_representation(pi, format, ap);
1432 		va_end(ap);
1433 	}
1434 	va_start(ap, format);
1435 	vprintf(format, ap);
1436 	va_end(ap);
1437 	printf("\n");
1438 
1439 	return pi;
1440 }
1441 
1442 proto_item *
proto_tree_add_format_text(proto_tree * tree,tvbuff_t * tvb,gint start,gint length)1443 proto_tree_add_format_text(proto_tree *tree, tvbuff_t *tvb, gint start, gint length)
1444 {
1445 	proto_item	  *pi;
1446 	header_field_info *hfinfo;
1447 
1448 	CHECK_FOR_NULL_TREE(tree);
1449 
1450 	TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1451 
1452 	pi = proto_tree_add_text_node(tree, tvb, start, length);
1453 
1454 	TRY_TO_FAKE_THIS_REPR(pi);
1455 
1456 	proto_item_set_text(pi, "%s", tvb_format_text(tree->tree_data->pinfo->pool, tvb, start, length));
1457 
1458 	return pi;
1459 }
1460 
1461 proto_item *
proto_tree_add_format_wsp_text(proto_tree * tree,tvbuff_t * tvb,gint start,gint length)1462 proto_tree_add_format_wsp_text(proto_tree *tree, tvbuff_t *tvb, gint start, gint length)
1463 {
1464 	proto_item	  *pi;
1465 	header_field_info *hfinfo;
1466 	gchar		  *str;
1467 
1468 	CHECK_FOR_NULL_TREE(tree);
1469 
1470 	TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1471 
1472 	pi = proto_tree_add_text_node(tree, tvb, start, length);
1473 
1474 	TRY_TO_FAKE_THIS_REPR(pi);
1475 
1476 	str = tvb_format_text_wsp(NULL, tvb, start, length);
1477 	proto_item_set_text(pi, "%s", str);
1478 	wmem_free(NULL, str);
1479 
1480 	return pi;
1481 }
1482 
proto_report_dissector_bug(const char * format,...)1483 void proto_report_dissector_bug(const char *format, ...)
1484 {
1485 	va_list args;
1486 
1487 	if (wireshark_abort_on_dissector_bug) {
1488 		/*
1489 		 * Try to have the error message show up in the crash
1490 		 * information.
1491 		 */
1492 		va_start(args, format);
1493 		ws_vadd_crash_info(format, args);
1494 		va_end(args);
1495 
1496 		/*
1497 		 * Print the error message.
1498 		 */
1499 		va_start(args, format);
1500 		vfprintf(stderr, format, args);
1501 		va_end(args);
1502 		putc('\n', stderr);
1503 
1504 		/*
1505 		 * And crash.
1506 		 */
1507 		abort();
1508 	} else {
1509 		va_start(args, format);
1510 		VTHROW_FORMATTED(DissectorError, format, args);
1511 		va_end(args);
1512 	}
1513 }
1514 
1515 /* We could probably get away with changing is_error to a minimum length value. */
1516 static void
report_type_length_mismatch(proto_tree * tree,const gchar * descr,int length,gboolean is_error)1517 report_type_length_mismatch(proto_tree *tree, const gchar *descr, int length, gboolean is_error)
1518 {
1519 	if (is_error) {
1520 		expert_add_info_format(NULL, tree, &ei_type_length_mismatch_error, "Trying to fetch %s with length %d", descr, length);
1521 	} else {
1522 		expert_add_info_format(NULL, tree, &ei_type_length_mismatch_warn, "Trying to fetch %s with length %d", descr, length);
1523 	}
1524 
1525 	if (is_error) {
1526 		THROW(ReportedBoundsError);
1527 	}
1528 }
1529 
1530 static guint32
get_uint_value(proto_tree * tree,tvbuff_t * tvb,gint offset,gint length,const guint encoding)1531 get_uint_value(proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, const guint encoding)
1532 {
1533 	guint32 value;
1534 	gboolean length_error;
1535 
1536 	switch (length) {
1537 
1538 	case 1:
1539 		value = tvb_get_guint8(tvb, offset);
1540 		if (encoding & ENC_ZIGBEE) {
1541 			if (value == 0xFF) { /* Invalid Zigbee length, set to 0 */
1542 				value = 0;
1543 			}
1544 		}
1545 		break;
1546 
1547 	case 2:
1548 		value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohs(tvb, offset)
1549 						       : tvb_get_ntohs(tvb, offset);
1550 		if (encoding & ENC_ZIGBEE) {
1551 			if (value == 0xFFFF) { /* Invalid Zigbee length, set to 0 */
1552 				value = 0;
1553 			}
1554 		}
1555 		break;
1556 
1557 	case 3:
1558 		value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh24(tvb, offset)
1559 						       : tvb_get_ntoh24(tvb, offset);
1560 		break;
1561 
1562 	case 4:
1563 		value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohl(tvb, offset)
1564 						       : tvb_get_ntohl(tvb, offset);
1565 		break;
1566 
1567 	default:
1568 		if (length < 1) {
1569 			length_error = TRUE;
1570 			value = 0;
1571 		} else {
1572 			length_error = FALSE;
1573 			value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohl(tvb, offset)
1574 							       : tvb_get_ntohl(tvb, offset);
1575 		}
1576 		report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1577 		break;
1578 	}
1579 	return value;
1580 }
1581 
1582 static inline guint64
get_uint64_value(proto_tree * tree,tvbuff_t * tvb,gint offset,guint length,const guint encoding)1583 get_uint64_value(proto_tree *tree, tvbuff_t *tvb, gint offset, guint length, const guint encoding)
1584 {
1585 	guint64 value;
1586 	gboolean length_error;
1587 
1588 	switch (length) {
1589 
1590 	case 1:
1591 		value = tvb_get_guint8(tvb, offset);
1592 		break;
1593 
1594 	case 2:
1595 		value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohs(tvb, offset)
1596 						       : tvb_get_ntohs(tvb, offset);
1597 		break;
1598 
1599 	case 3:
1600 		value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh24(tvb, offset)
1601 						       : tvb_get_ntoh24(tvb, offset);
1602 		break;
1603 
1604 	case 4:
1605 		value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohl(tvb, offset)
1606 						       : tvb_get_ntohl(tvb, offset);
1607 		break;
1608 
1609 	case 5:
1610 		value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh40(tvb, offset)
1611 						       : tvb_get_ntoh40(tvb, offset);
1612 		break;
1613 
1614 	case 6:
1615 		value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh48(tvb, offset)
1616 						       : tvb_get_ntoh48(tvb, offset);
1617 		break;
1618 
1619 	case 7:
1620 		value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh56(tvb, offset)
1621 						       : tvb_get_ntoh56(tvb, offset);
1622 		break;
1623 
1624 	case 8:
1625 		value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh64(tvb, offset)
1626 						       : tvb_get_ntoh64(tvb, offset);
1627 		break;
1628 
1629 	default:
1630 		if (length < 1) {
1631 			length_error = TRUE;
1632 			value = 0;
1633 		} else {
1634 			length_error = FALSE;
1635 			value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh64(tvb, offset)
1636 							       : tvb_get_ntoh64(tvb, offset);
1637 		}
1638 		report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1639 		break;
1640 	}
1641 	return value;
1642 }
1643 
1644 static gint32
get_int_value(proto_tree * tree,tvbuff_t * tvb,gint offset,gint length,const guint encoding)1645 get_int_value(proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, const guint encoding)
1646 {
1647 	gint32 value;
1648 	gboolean length_error;
1649 
1650 	switch (length) {
1651 
1652 	case 1:
1653 		value = tvb_get_gint8(tvb, offset);
1654 		break;
1655 
1656 	case 2:
1657 		value = encoding ? tvb_get_letohis(tvb, offset)
1658 				 : tvb_get_ntohis(tvb, offset);
1659 		break;
1660 
1661 	case 3:
1662 		value = encoding ? tvb_get_letohi24(tvb, offset)
1663 				 : tvb_get_ntohi24(tvb, offset);
1664 		break;
1665 
1666 	case 4:
1667 		value = encoding ? tvb_get_letohil(tvb, offset)
1668 				 : tvb_get_ntohil(tvb, offset);
1669 		break;
1670 
1671 	default:
1672 		if (length < 1) {
1673 			length_error = TRUE;
1674 			value = 0;
1675 		} else {
1676 			length_error = FALSE;
1677 			value = encoding ? tvb_get_letohil(tvb, offset)
1678 					 : tvb_get_ntohil(tvb, offset);
1679 		}
1680 		report_type_length_mismatch(tree, "a signed integer", length, length_error);
1681 		break;
1682 	}
1683 	return value;
1684 }
1685 
1686 /* Note: this returns an unsigned int64, but with the appropriate bit(s) set to
1687  * be cast-able as a gint64. This is weird, but what the code has always done.
1688  */
1689 static inline guint64
get_int64_value(proto_tree * tree,tvbuff_t * tvb,gint start,guint length,const guint encoding)1690 get_int64_value(proto_tree *tree, tvbuff_t *tvb, gint start, guint length, const guint encoding)
1691 {
1692 	guint64 value = get_uint64_value(tree, tvb, start, length, encoding);
1693 
1694 	switch (length) {
1695 		case 7:
1696 			value = ws_sign_ext64(value, 56);
1697 			break;
1698 		case 6:
1699 			value = ws_sign_ext64(value, 48);
1700 			break;
1701 		case 5:
1702 			value = ws_sign_ext64(value, 40);
1703 			break;
1704 		case 4:
1705 			value = ws_sign_ext64(value, 32);
1706 			break;
1707 		case 3:
1708 			value = ws_sign_ext64(value, 24);
1709 			break;
1710 		case 2:
1711 			value = ws_sign_ext64(value, 16);
1712 			break;
1713 		case 1:
1714 			value = ws_sign_ext64(value, 8);
1715 			break;
1716 	}
1717 
1718 	return value;
1719 }
1720 
1721 /* For FT_STRING */
1722 static inline const guint8 *
get_string_value(wmem_allocator_t * scope,tvbuff_t * tvb,gint start,gint length,gint * ret_length,const guint encoding)1723 get_string_value(wmem_allocator_t *scope, tvbuff_t *tvb, gint start,
1724     gint length, gint *ret_length, const guint encoding)
1725 {
1726 	if (length == -1) {
1727 		length = tvb_ensure_captured_length_remaining(tvb, start);
1728 	}
1729 	*ret_length = length;
1730 	return tvb_get_string_enc(scope, tvb, start, length, encoding);
1731 }
1732 
1733 /* For FT_STRINGZ */
1734 static inline const guint8 *
get_stringz_value(wmem_allocator_t * scope,proto_tree * tree,tvbuff_t * tvb,gint start,gint length,gint * ret_length,const guint encoding)1735 get_stringz_value(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb,
1736     gint start, gint length, gint *ret_length, const guint encoding)
1737 {
1738 	const guint8 *value;
1739 
1740 	if (length < -1) {
1741 		report_type_length_mismatch(tree, "a string", length, TRUE);
1742 	}
1743 	if (length == -1) {
1744 		/* This can throw an exception */
1745 		value = tvb_get_stringz_enc(scope, tvb, start, &length, encoding);
1746 	} else {
1747 		/* In this case, length signifies the length of the string.
1748 		 *
1749 		 * This could either be a null-padded string, which doesn't
1750 		 * necessarily have a '\0' at the end, or a null-terminated
1751 		 * string, with a trailing '\0'.  (Yes, there are cases
1752 		 * where you have a string that's both counted and null-
1753 		 * terminated.)
1754 		 *
1755 		 * In the first case, we must allocate a buffer of length
1756 		 * "length+1", to make room for a trailing '\0'.
1757 		 *
1758 		 * In the second case, we don't assume that there is a
1759 		 * trailing '\0' there, as the packet might be malformed.
1760 		 * (XXX - should we throw an exception if there's no
1761 		 * trailing '\0'?)  Therefore, we allocate a buffer of
1762 		 * length "length+1", and put in a trailing '\0', just to
1763 		 * be safe.
1764 		 *
1765 		 * (XXX - this would change if we made string values counted
1766 		 * rather than null-terminated.)
1767 		 */
1768 		value = tvb_get_string_enc(scope, tvb, start, length, encoding);
1769 	}
1770 	*ret_length = length;
1771 	return value;
1772 }
1773 
1774 /* For FT_UINT_STRING */
1775 static inline const guint8 *
get_uint_string_value(wmem_allocator_t * scope,proto_tree * tree,tvbuff_t * tvb,gint start,gint length,gint * ret_length,const guint encoding)1776 get_uint_string_value(wmem_allocator_t *scope, proto_tree *tree,
1777     tvbuff_t *tvb, gint start, gint length, gint *ret_length,
1778     const guint encoding)
1779 {
1780 	guint32 n;
1781 	const guint8 *value;
1782 
1783 	/* I believe it's ok if this is called with a NULL tree */
1784 	n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK);
1785 	value = tvb_get_string_enc(scope, tvb, start + length, n, encoding);
1786 	length += n;
1787 	*ret_length = length;
1788 	return value;
1789 }
1790 
1791 /* For FT_STRINGZPAD */
1792 static inline const guint8 *
get_stringzpad_value(wmem_allocator_t * scope,tvbuff_t * tvb,gint start,gint length,gint * ret_length,const guint encoding)1793 get_stringzpad_value(wmem_allocator_t *scope, tvbuff_t *tvb, gint start,
1794     gint length, gint *ret_length, const guint encoding)
1795 {
1796 	/*
1797 	 * XXX - currently, string values are null-
1798 	 * terminated, so a "zero-padded" string
1799 	 * isn't special.  If we represent string
1800 	 * values as something that includes a counted
1801 	 * array of bytes, we'll need to strip the
1802 	 * trailing NULs.
1803 	 */
1804 	if (length == -1) {
1805 		length = tvb_ensure_captured_length_remaining(tvb, start);
1806 	}
1807 	*ret_length = length;
1808 	return tvb_get_string_enc(scope, tvb, start, length, encoding);
1809 }
1810 
1811 /* For FT_STRINGZTRUNC */
1812 static inline const guint8 *
get_stringztrunc_value(wmem_allocator_t * scope,tvbuff_t * tvb,gint start,gint length,gint * ret_length,const guint encoding)1813 get_stringztrunc_value(wmem_allocator_t *scope, tvbuff_t *tvb, gint start,
1814     gint length, gint *ret_length, const guint encoding)
1815 {
1816 	/*
1817 	 * XXX - currently, string values are null-
1818 	 * terminated, so a "zero-truncated" string
1819 	 * isn't special.  If we represent string
1820 	 * values as something that includes a counted
1821 	 * array of bytes, we'll need to strip everything
1822 	 * starting with the terminating NUL.
1823 	 */
1824 	if (length == -1) {
1825 		length = tvb_ensure_captured_length_remaining(tvb, start);
1826 	}
1827 	*ret_length = length;
1828 	return tvb_get_string_enc(scope, tvb, start, length, encoding);
1829 }
1830 
1831 /*
1832  * Deltas between the epochs for various non-UN*X time stamp formats and
1833  * the January 1, 1970, 00:00:00 (proleptic?) UTC epoch for the UN*X time
1834  * stamp format.
1835  */
1836 
1837 /*
1838  * NTP Era 0: the epoch is January 1, 1900, 00:00:00 (proleptic?) UTC.
1839  * XXX - if it's OK if this is unsigned, can we just use
1840  * EPOCH_DELTA_1900_01_01_00_00_00_UTC?
1841  */
1842 #define NTP_TIMEDIFF1900TO1970SEC G_GINT64_CONSTANT(2208988800)
1843 
1844 /*
1845  * NTP Era 1: the epoch is January 1, 2036, 00:00:00 UTC.
1846  */
1847 #define NTP_TIMEDIFF1970TO2036SEC G_GINT64_CONSTANT(2085978496)
1848 
1849 /* this can be called when there is no tree, so tree may be null */
1850 static void
get_time_value(proto_tree * tree,tvbuff_t * tvb,const gint start,const gint length,const guint encoding,nstime_t * time_stamp,const gboolean is_relative)1851 get_time_value(proto_tree *tree, tvbuff_t *tvb, const gint start,
1852 	       const gint length, const guint encoding, nstime_t *time_stamp,
1853 	       const gboolean is_relative)
1854 {
1855 	guint32     tmpsecs;
1856 	guint64     tmp64secs;
1857 	guint64     todusecs;
1858 
1859 	switch (encoding) {
1860 
1861 		case ENC_TIME_SECS_NSECS|ENC_BIG_ENDIAN:
1862 			/*
1863 			 * If the length is 16, 8-byte seconds, followed
1864 			 * by 8-byte fractional time in nanoseconds,
1865 			 * both big-endian.
1866 			 *
1867 			 * If the length is 12, 8-byte seconds, followed
1868 			 * by 4-byte fractional time in nanoseconds,
1869 			 * both big-endian.
1870 			 *
1871 			 * If the length is 8, 4-byte seconds, followed
1872 			 * by 4-byte fractional time in nanoseconds,
1873 			 * both big-endian.
1874 			 *
1875 			 * For absolute times, the seconds are seconds
1876 			 * since the UN*X epoch.
1877 			 */
1878 			if (length == 16) {
1879 				time_stamp->secs  = (time_t)tvb_get_ntoh64(tvb, start);
1880 				time_stamp->nsecs = (guint32)tvb_get_ntoh64(tvb, start+8);
1881 			} else if (length == 12) {
1882 				time_stamp->secs  = (time_t)tvb_get_ntoh64(tvb, start);
1883 				time_stamp->nsecs = tvb_get_ntohl(tvb, start+8);
1884 			} else if (length == 8) {
1885 				time_stamp->secs  = (time_t)tvb_get_ntohl(tvb, start);
1886 				time_stamp->nsecs = tvb_get_ntohl(tvb, start+4);
1887 			} else if (length == 4) {
1888 				/*
1889 				 * Backwards compatibility.
1890 				 * ENC_TIME_SECS_NSECS is 0; using
1891 				 * ENC_BIG_ENDIAN by itself with a 4-byte
1892 				 * time-in-seconds value was done in the
1893 				 * past.
1894 				 */
1895 				time_stamp->secs  = (time_t)tvb_get_ntohl(tvb, start);
1896 				time_stamp->nsecs = 0;
1897 			} else {
1898 				time_stamp->secs  = 0;
1899 				time_stamp->nsecs = 0;
1900 				report_type_length_mismatch(tree, "a timespec", length, (length < 4));
1901 			}
1902 			break;
1903 
1904 		case ENC_TIME_SECS_NSECS|ENC_LITTLE_ENDIAN:
1905 			/*
1906 			 * If the length is 16, 8-byte seconds, followed
1907 			 * by 8-byte fractional time in nanoseconds,
1908 			 * both little-endian.
1909 			 *
1910 			 * If the length is 12, 8-byte seconds, followed
1911 			 * by 4-byte fractional time in nanoseconds,
1912 			 * both little-endian.
1913 			 *
1914 			 * If the length is 8, 4-byte seconds, followed
1915 			 * by 4-byte fractional time in nanoseconds,
1916 			 * both little-endian.
1917 			 *
1918 			 * For absolute times, the seconds are seconds
1919 			 * since the UN*X epoch.
1920 			 */
1921 			if (length == 16) {
1922 				time_stamp->secs  = (time_t)tvb_get_letoh64(tvb, start);
1923 				time_stamp->nsecs = (guint32)tvb_get_letoh64(tvb, start+8);
1924 			} else if (length == 12) {
1925 				time_stamp->secs  = (time_t)tvb_get_letoh64(tvb, start);
1926 				time_stamp->nsecs = tvb_get_letohl(tvb, start+8);
1927 			} else if (length == 8) {
1928 				time_stamp->secs  = (time_t)tvb_get_letohl(tvb, start);
1929 				time_stamp->nsecs = tvb_get_letohl(tvb, start+4);
1930 			} else if (length == 4) {
1931 				/*
1932 				 * Backwards compatibility.
1933 				 * ENC_TIME_SECS_NSECS is 0; using
1934 				 * ENC_LITTLE_ENDIAN by itself with a 4-byte
1935 				 * time-in-seconds value was done in the
1936 				 * past.
1937 				 */
1938 				time_stamp->secs  = (time_t)tvb_get_letohl(tvb, start);
1939 				time_stamp->nsecs = 0;
1940 			} else {
1941 				time_stamp->secs  = 0;
1942 				time_stamp->nsecs = 0;
1943 				report_type_length_mismatch(tree, "a timespec", length, (length < 4));
1944 			}
1945 			break;
1946 
1947 		case ENC_TIME_NTP|ENC_BIG_ENDIAN:
1948 			/*
1949 			 * NTP time stamp, big-endian.
1950 			 * Only supported for absolute times.
1951 			 */
1952 			DISSECTOR_ASSERT(!is_relative);
1953 
1954 			/* We need a temporary variable here so the unsigned math
1955 			 * works correctly (for years > 2036 according to RFC 2030
1956 			 * chapter 3).
1957 			 *
1958 			 * If bit 0 is set, the UTC time is in the range 1968-2036 and
1959 			 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
1960 			 * If bit 0 is not set, the time is in the range 2036-2104 and
1961 			 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
1962 			 */
1963 			tmpsecs  = tvb_get_ntohl(tvb, start);
1964 			if ((tmpsecs & 0x80000000) != 0)
1965 				time_stamp->secs = (time_t)((gint64)tmpsecs - NTP_TIMEDIFF1900TO1970SEC);
1966 			else
1967 				time_stamp->secs = (time_t)((gint64)tmpsecs + NTP_TIMEDIFF1970TO2036SEC);
1968 
1969 			if (length == 8) {
1970 				/*
1971 				 * Convert 1/2^32s of a second to nanoseconds.
1972 				 */
1973 				time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
1974 				if ((time_stamp->nsecs == 0) && (tmpsecs == 0)) {
1975 					//This is "NULL" time
1976 					time_stamp->secs = 0;
1977 				}
1978 			} else if (length == 4) {
1979 				/*
1980 				 * Backwards compatibility.
1981 				 */
1982 				if (tmpsecs == 0) {
1983 					//This is "NULL" time
1984 					time_stamp->secs = 0;
1985 				}
1986 				time_stamp->nsecs = 0;
1987 			} else {
1988 				time_stamp->secs  = 0;
1989 				time_stamp->nsecs = 0;
1990 				report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
1991 			}
1992 			break;
1993 
1994 		case ENC_TIME_NTP|ENC_LITTLE_ENDIAN:
1995 			/*
1996 			 * NTP time stamp, little-endian.
1997 			 * Only supported for absolute times.
1998 			 */
1999 			DISSECTOR_ASSERT(!is_relative);
2000 
2001 			/* We need a temporary variable here so the unsigned math
2002 			 * works correctly (for years > 2036 according to RFC 2030
2003 			 * chapter 3).
2004 			 *
2005 			 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2006 			 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2007 			 * If bit 0 is not set, the time is in the range 2036-2104 and
2008 			 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2009 			 */
2010 			tmpsecs  = tvb_get_letohl(tvb, start);
2011 			if ((tmpsecs & 0x80000000) != 0)
2012 				time_stamp->secs = (time_t)((gint64)tmpsecs - NTP_TIMEDIFF1900TO1970SEC);
2013 			else
2014 				time_stamp->secs = (time_t)((gint64)tmpsecs + NTP_TIMEDIFF1970TO2036SEC);
2015 
2016 			if (length == 8) {
2017 				/*
2018 				 * Convert 1/2^32s of a second to nanoseconds.
2019 				 */
2020 				time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2021 				if ((time_stamp->nsecs == 0) && (tmpsecs == 0)) {
2022 					//This is "NULL" time
2023 					time_stamp->secs = 0;
2024 				}
2025 			} else if (length == 4) {
2026 				/*
2027 				 * Backwards compatibility.
2028 				 */
2029 				if (tmpsecs == 0) {
2030 					//This is "NULL" time
2031 					time_stamp->secs = 0;
2032 				}
2033 				time_stamp->nsecs = 0;
2034 			} else {
2035 				time_stamp->secs  = 0;
2036 				time_stamp->nsecs = 0;
2037 				report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2038 			}
2039 			break;
2040 
2041 		case ENC_TIME_TOD|ENC_BIG_ENDIAN:
2042 			/*
2043 			 * S/3x0 and z/Architecture TOD clock time stamp,
2044 			 * big-endian.  The epoch is January 1, 1900,
2045 			 * 00:00:00 (proleptic?) UTC.
2046 			 *
2047 			 * Only supported for absolute times.
2048 			 */
2049 			DISSECTOR_ASSERT(!is_relative);
2050 			DISSECTOR_ASSERT(length == 8);
2051 
2052 			if (length == 8) {
2053 				todusecs  = tvb_get_ntoh64(tvb, start) >> 12;
2054 				time_stamp->secs = (time_t)((todusecs  / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC);
2055 				time_stamp->nsecs = (int)((todusecs  % 1000000) * 1000);
2056 			} else {
2057 				time_stamp->secs  = 0;
2058 				time_stamp->nsecs = 0;
2059 				report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2060 			}
2061 			break;
2062 
2063 		case ENC_TIME_TOD|ENC_LITTLE_ENDIAN:
2064 			/*
2065 			 * S/3x0 and z/Architecture TOD clock time stamp,
2066 			 * little-endian.  The epoch is January 1, 1900,
2067 			 * 00:00:00 (proleptic?) UTC.
2068 			 *
2069 			 * Only supported for absolute times.
2070 			 */
2071 			DISSECTOR_ASSERT(!is_relative);
2072 
2073 			if (length == 8) {
2074 				todusecs  = tvb_get_letoh64(tvb, start) >> 12 ;
2075 				time_stamp->secs = (time_t)((todusecs  / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC);
2076 				time_stamp->nsecs = (int)((todusecs  % 1000000) * 1000);
2077 			} else {
2078 				time_stamp->secs  = 0;
2079 				time_stamp->nsecs = 0;
2080 				report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2081 			}
2082 			break;
2083 
2084 		case ENC_TIME_RTPS|ENC_BIG_ENDIAN:
2085 			/*
2086 			 * Time stamp using the same seconds/fraction format
2087 			 * as NTP, but with the origin of the time stamp being
2088 			 * the UNIX epoch rather than the NTP epoch; big-
2089 			 * endian.
2090 			 *
2091 			 * Only supported for absolute times.
2092 			 */
2093 			DISSECTOR_ASSERT(!is_relative);
2094 
2095 			if (length == 8) {
2096 				time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2097 				/*
2098 				 * Convert 1/2^32s of a second to nanoseconds.
2099 				 */
2100 				time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2101 			} else {
2102 				time_stamp->secs  = 0;
2103 				time_stamp->nsecs = 0;
2104 				report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2105 			}
2106 			break;
2107 
2108 		case ENC_TIME_RTPS|ENC_LITTLE_ENDIAN:
2109 			/*
2110 			 * Time stamp using the same seconds/fraction format
2111 			 * as NTP, but with the origin of the time stamp being
2112 			 * the UNIX epoch rather than the NTP epoch; little-
2113 			 * endian.
2114 			 *
2115 			 * Only supported for absolute times.
2116 			 */
2117 			DISSECTOR_ASSERT(!is_relative);
2118 
2119 			if (length == 8) {
2120 				time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2121 				/*
2122 				 * Convert 1/2^32s of a second to nanoseconds.
2123 				 */
2124 				time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2125 			} else {
2126 				time_stamp->secs  = 0;
2127 				time_stamp->nsecs = 0;
2128 				report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2129 			}
2130 			break;
2131 
2132 		case ENC_TIME_MIP6 | ENC_BIG_ENDIAN:
2133 			/*
2134 			* MIP6 time stamp, big-endian.
2135 			* A 64-bit unsigned integer field containing a timestamp.  The
2136 			* value indicates the number of seconds since January 1, 1970,
2137 			* 00:00 UTC, by using a fixed point format.  In this format, the
2138 			* integer number of seconds is contained in the first 48 bits of
2139 			* the field, and the remaining 16 bits indicate the number of
2140 			* 1/65536 fractions of a second.
2141 
2142 			* Only supported for absolute times.
2143 			*/
2144 			DISSECTOR_ASSERT(!is_relative);
2145 
2146 			if (length == 8) {
2147 				/* We need a temporary variable here so the casting and fractions
2148 				* of a second work correctly.
2149 				*/
2150 				tmp64secs = tvb_get_ntoh48(tvb, start);
2151 				tmpsecs = tvb_get_ntohs(tvb, start + 6);
2152 				tmpsecs <<= 16;
2153 
2154 				if ((tmp64secs == 0) && (tmpsecs == 0)) {
2155 					//This is "NULL" time
2156 					time_stamp->secs = 0;
2157 					time_stamp->nsecs = 0;
2158 				} else {
2159 					time_stamp->secs = (time_t)tmp64secs;
2160 					time_stamp->nsecs = (int)((tmpsecs / 4294967296.0) * 1000000000);
2161 				}
2162 			} else {
2163 				time_stamp->secs = 0;
2164 				time_stamp->nsecs = 0;
2165 				report_type_length_mismatch(tree, "an NTP time stamp", length, (length != 8));
2166 			}
2167 			break;
2168 
2169 		case ENC_TIME_SECS_USECS|ENC_BIG_ENDIAN:
2170 			/*
2171 			 * 4-byte seconds, followed by 4-byte fractional
2172 			 * time in microseconds, both big-endian.
2173 			 * For absolute times, the seconds are seconds
2174 			 * since the UN*X epoch.
2175 			 */
2176 			if (length == 8) {
2177 				time_stamp->secs  = (time_t)tvb_get_ntohl(tvb, start);
2178 				time_stamp->nsecs = tvb_get_ntohl(tvb, start+4)*1000;
2179 			} else {
2180 				time_stamp->secs  = 0;
2181 				time_stamp->nsecs = 0;
2182 				report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2183 			}
2184 			break;
2185 
2186 		case ENC_TIME_SECS_USECS|ENC_LITTLE_ENDIAN:
2187 			/*
2188 			 * 4-byte seconds, followed by 4-byte fractional
2189 			 * time in microseconds, both little-endian.
2190 			 * For absolute times, the seconds are seconds
2191 			 * since the UN*X epoch.
2192 			 */
2193 			if (length == 8) {
2194 				time_stamp->secs  = (time_t)tvb_get_letohl(tvb, start);
2195 				time_stamp->nsecs = tvb_get_letohl(tvb, start+4)*1000;
2196 			} else {
2197 				time_stamp->secs  = 0;
2198 				time_stamp->nsecs = 0;
2199 				report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2200 			}
2201 			break;
2202 
2203 		case ENC_TIME_SECS|ENC_BIG_ENDIAN:
2204 		case ENC_TIME_SECS|ENC_LITTLE_ENDIAN:
2205 			/*
2206 			 * Seconds, 1 to 8 bytes.
2207 			 * For absolute times, it's seconds since the
2208 			 * UN*X epoch.
2209 			 */
2210 			if (length >= 1 && length <= 8) {
2211 				time_stamp->secs  = (time_t)get_uint64_value(tree, tvb, start, length, encoding);
2212 				time_stamp->nsecs = 0;
2213 			} else {
2214 				time_stamp->secs  = 0;
2215 				time_stamp->nsecs = 0;
2216 				report_type_length_mismatch(tree, "a time-in-seconds time stamp", length, (length < 4));
2217 			}
2218 			break;
2219 
2220 		case ENC_TIME_MSECS|ENC_BIG_ENDIAN:
2221 		case ENC_TIME_MSECS|ENC_LITTLE_ENDIAN:
2222 			/*
2223 			 * Milliseconds, 1 to 8 bytes.
2224 			 * For absolute times, it's milliseconds since the
2225 			 * UN*X epoch.
2226 			 */
2227 			if (length >= 1 && length <= 8) {
2228 				guint64 msecs;
2229 
2230 				msecs = get_uint64_value(tree, tvb, start, length, encoding);
2231 				time_stamp->secs  = (time_t)(msecs / 1000);
2232 				time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2233 			} else {
2234 				time_stamp->secs  = 0;
2235 				time_stamp->nsecs = 0;
2236 				report_type_length_mismatch(tree, "a time-in-milliseconds time stamp", length, (length < 4));
2237 			}
2238 			break;
2239 
2240 		case ENC_TIME_NSECS|ENC_BIG_ENDIAN:
2241 		case ENC_TIME_NSECS|ENC_LITTLE_ENDIAN:
2242 			/*
2243 			 * nanoseconds, 1 to 8 bytes.
2244 			 * For absolute times, it's nanoseconds since the
2245 			 * UN*X epoch.
2246 			 */
2247 
2248 			if (length >= 1 && length <= 8) {
2249 				guint64 nsecs;
2250 
2251 				nsecs = get_uint64_value(tree, tvb, start, length, encoding);
2252 				time_stamp->secs  = (time_t)(nsecs / 1000000000);
2253 				time_stamp->nsecs = (int)(nsecs % 1000000000);
2254 			} else {
2255 				time_stamp->secs  = 0;
2256 				time_stamp->nsecs = 0;
2257 				report_type_length_mismatch(tree, "a time-in-nanoseconds time stamp", length, (length < 4));
2258 			}
2259 			break;
2260 
2261 		case ENC_TIME_RFC_3971|ENC_BIG_ENDIAN:
2262 			/*
2263 			 * 1/64ths of a second since the UN*X epoch,
2264 			 * big-endian.
2265 			 *
2266 			 * Only supported for absolute times.
2267 			 */
2268 			DISSECTOR_ASSERT(!is_relative);
2269 
2270 			if (length == 8) {
2271 				/*
2272 				 * The upper 48 bits are seconds since the
2273 				 * UN*X epoch.
2274 				 */
2275 				time_stamp->secs  = (time_t)tvb_get_ntoh48(tvb, start);
2276 				/*
2277 				 * The lower 16 bits are 1/2^16s of a second;
2278 				 * convert them to nanoseconds.
2279 				 *
2280 				 * XXX - this may give the impression of higher
2281 				 * precision than you actually get.
2282 				 */
2283 				time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohs(tvb, start+6)/65536.0));
2284 			} else {
2285 				time_stamp->secs  = 0;
2286 				time_stamp->nsecs = 0;
2287 				report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2288 			}
2289 			break;
2290 
2291 		case ENC_TIME_RFC_3971|ENC_LITTLE_ENDIAN:
2292 			/*
2293 			 * 1/64ths of a second since the UN*X epoch,
2294 			 * little-endian.
2295 			 *
2296 			 * Only supported for absolute times.
2297 			 */
2298 			DISSECTOR_ASSERT(!is_relative);
2299 
2300 			if (length == 8) {
2301 				/*
2302 				 * XXX - this is assuming that, if anybody
2303 				 * were ever to use this format - RFC 3971
2304 				 * doesn't, because that's an Internet
2305 				 * protocol, and those use network byte
2306 				 * order, i.e. big-endian - they'd treat it
2307 				 * as a 64-bit count of 1/2^16s of a second,
2308 				 * putting the upper 48 bits at the end.
2309 				 *
2310 				 * The lower 48 bits are seconds since the
2311 				 * UN*X epoch.
2312 				 */
2313 				time_stamp->secs  = (time_t)tvb_get_letoh48(tvb, start+2);
2314 				/*
2315 				 * The upper 16 bits are 1/2^16s of a second;
2316 				 * convert them to nanoseconds.
2317 				 *
2318 				 * XXX - this may give the impression of higher
2319 				 * precision than you actually get.
2320 				 */
2321 				time_stamp->nsecs = (int)(1000000000*(tvb_get_letohs(tvb, start)/65536.0));
2322 			} else {
2323 				time_stamp->secs  = 0;
2324 				time_stamp->nsecs = 0;
2325 				report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2326 			}
2327 			break;
2328 
2329 		case ENC_TIME_SECS_NTP|ENC_BIG_ENDIAN:
2330 			/*
2331 			 * NTP time stamp, with 1-second resolution (i.e.,
2332 			 * seconds since the NTP epoch), big-endian.
2333 			 * Only supported for absolute times.
2334 			 */
2335 			DISSECTOR_ASSERT(!is_relative);
2336 
2337 			if (length == 4) {
2338 				/*
2339 				* We need a temporary variable here so the unsigned math
2340 				* works correctly (for years > 2036 according to RFC 2030
2341 				* chapter 3).
2342 				*
2343 				* If bit 0 is set, the UTC time is in the range 1968-2036 and
2344 				* UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2345 				* If bit 0 is not set, the time is in the range 2036-2104 and
2346 				* UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2347 				*/
2348 				tmpsecs  = tvb_get_ntohl(tvb, start);
2349 				if ((tmpsecs & 0x80000000) != 0)
2350 					time_stamp->secs = (time_t)((gint64)tmpsecs - NTP_TIMEDIFF1900TO1970SEC);
2351 				else
2352 					time_stamp->secs = (time_t)((gint64)tmpsecs + NTP_TIMEDIFF1970TO2036SEC);
2353 				time_stamp->nsecs = 0;
2354 			} else {
2355 				time_stamp->secs  = 0;
2356 				time_stamp->nsecs = 0;
2357 				report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2358 			}
2359 			break;
2360 
2361 		case ENC_TIME_SECS_NTP|ENC_LITTLE_ENDIAN:
2362 			/*
2363 			 * NTP time stamp, with 1-second resolution (i.e.,
2364 			 * seconds since the NTP epoch), little-endian.
2365 			 * Only supported for absolute times.
2366 			 */
2367 			DISSECTOR_ASSERT(!is_relative);
2368 
2369 			/*
2370 			 * We need a temporary variable here so the unsigned math
2371 			 * works correctly (for years > 2036 according to RFC 2030
2372 			 * chapter 3).
2373 			 *
2374 			 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2375 			 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2376 			 * If bit 0 is not set, the time is in the range 2036-2104 and
2377 			 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2378 			 */
2379 			if (length == 4) {
2380 				tmpsecs  = tvb_get_letohl(tvb, start);
2381 				if ((tmpsecs & 0x80000000) != 0)
2382 					time_stamp->secs = (time_t)((gint64)tmpsecs - NTP_TIMEDIFF1900TO1970SEC);
2383 				else
2384 					time_stamp->secs = (time_t)((gint64)tmpsecs + NTP_TIMEDIFF1970TO2036SEC);
2385 				time_stamp->nsecs = 0;
2386 			} else {
2387 				time_stamp->secs  = 0;
2388 				time_stamp->nsecs = 0;
2389 				report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2390 			}
2391 			break;
2392 		case ENC_TIME_MSEC_NTP | ENC_BIG_ENDIAN:
2393 			/*
2394 			* Milliseconds, 1 to 8 bytes.
2395 			* For absolute times, it's milliseconds since the
2396 			* NTP epoch.
2397 			*/
2398 			if (length >= 1 && length <= 8) {
2399 				guint64 msecs;
2400 
2401 				msecs = get_uint64_value(tree, tvb, start, length, encoding);
2402 				tmpsecs = (guint32)(msecs / 1000);
2403 				/*
2404 				* If bit 0 is set, the UTC time is in the range 1968-2036 and
2405 				* UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2406 				* If bit 0 is not set, the time is in the range 2036-2104 and
2407 				* UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2408 				*/
2409 				if ((tmpsecs & 0x80000000) != 0)
2410 					time_stamp->secs = (time_t)((gint64)tmpsecs - NTP_TIMEDIFF1900TO1970SEC);
2411 				else
2412 					time_stamp->secs = (time_t)((gint64)tmpsecs + NTP_TIMEDIFF1970TO2036SEC);
2413 				time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2414 			}
2415 			else {
2416 				time_stamp->secs  = 0;
2417 				time_stamp->nsecs = 0;
2418 				report_type_length_mismatch(tree, "a time-in-milliseconds NTP time stamp", length, (length < 4));
2419 			}
2420 			break;
2421 
2422 		case ENC_TIME_CLASSIC_MAC_OS_SECS|ENC_BIG_ENDIAN:
2423 			/*
2424 			 * Classic Mac OS time stamps, big-endian.
2425 			 * Only supported for absolute times.
2426 			 */
2427 			DISSECTOR_ASSERT(!is_relative);
2428 
2429 			if (length == 8) {
2430 				tmp64secs  = tvb_get_ntoh64(tvb, start);
2431 				time_stamp->secs = (time_t)(gint64)(tmp64secs - EPOCH_DELTA_1904_01_01_00_00_00_UTC);
2432 				time_stamp->nsecs = 0;
2433 			} else if (length == 4) {
2434 				tmpsecs  = tvb_get_ntohl(tvb, start);
2435 				time_stamp->secs = (time_t)(gint32)(tmpsecs - EPOCH_DELTA_1904_01_01_00_00_00_UTC);
2436 				time_stamp->nsecs = 0;
2437 			} else {
2438 				time_stamp->secs  = 0;
2439 				time_stamp->nsecs = 0;
2440 				report_type_length_mismatch(tree, "an MP4 time stamp", length, (length < 4));
2441 			}
2442 			break;
2443 
2444 		default:
2445 			DISSECTOR_ASSERT_NOT_REACHED();
2446 			break;
2447 	}
2448 }
2449 
2450 static void
tree_data_add_maybe_interesting_field(tree_data_t * tree_data,field_info * fi)2451 tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
2452 {
2453 	const header_field_info *hfinfo = fi->hfinfo;
2454 
2455 	if (hfinfo->ref_type == HF_REF_TYPE_DIRECT) {
2456 		GPtrArray *ptrs = NULL;
2457 
2458 		if (tree_data->interesting_hfids == NULL) {
2459 			/* Initialize the hash because we now know that it is needed */
2460 			tree_data->interesting_hfids =
2461 				g_hash_table_new(g_direct_hash, NULL /* g_direct_equal */);
2462 		} else if (g_hash_table_size(tree_data->interesting_hfids)) {
2463 			ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
2464 					   GINT_TO_POINTER(hfinfo->id));
2465 		}
2466 
2467 		if (!ptrs) {
2468 			/* First element triggers the creation of pointer array */
2469 			ptrs = g_ptr_array_new();
2470 			g_hash_table_insert(tree_data->interesting_hfids,
2471 					    GINT_TO_POINTER(hfinfo->id), ptrs);
2472 		}
2473 
2474 		g_ptr_array_add(ptrs, fi);
2475 	}
2476 }
2477 
2478 
2479 /*
2480  * Validates that field length bytes are available starting from
2481  * start (pos/neg). Throws an exception if they aren't.
2482  */
2483 static void
test_length(header_field_info * hfinfo,tvbuff_t * tvb,gint start,gint length,const guint encoding)2484 test_length(header_field_info *hfinfo, tvbuff_t *tvb,
2485 	    gint start, gint length, const guint encoding)
2486 {
2487 	gint size = length;
2488 
2489 	if (!tvb)
2490 		return;
2491 
2492 	if ((hfinfo->type == FT_STRINGZ) ||
2493 	    ((encoding & (ENC_VARIANT_MASK)) &&
2494 	     (IS_FT_UINT(hfinfo->type) || IS_FT_INT(hfinfo->type)))) {
2495 		/* If we're fetching until the end of the TVB, only validate
2496 		 * that the offset is within range.
2497 		 */
2498 		if (length == -1)
2499 			size = 0;
2500 	}
2501 
2502 	tvb_ensure_bytes_exist(tvb, start, size);
2503 }
2504 
2505 static void
detect_trailing_stray_characters(guint encoding,const char * string,gint length,proto_item * pi)2506 detect_trailing_stray_characters(guint encoding, const char *string, gint length, proto_item *pi)
2507 {
2508 	gboolean found_stray_character = FALSE;
2509 
2510 	if (!string)
2511 		return;
2512 
2513 	switch (encoding & ENC_CHARENCODING_MASK) {
2514 		case ENC_ASCII:
2515 		case ENC_UTF_8:
2516 			for (gint i = (gint)strlen(string); i < length; i++) {
2517 				if (string[i] != '\0') {
2518 					found_stray_character = TRUE;
2519 					break;
2520 				}
2521 			}
2522 			break;
2523 
2524 		default:
2525 			break;
2526 	}
2527 
2528 	if (found_stray_character) {
2529 		expert_add_info(NULL, pi, &ei_string_trailing_characters);
2530 	}
2531 }
2532 
2533 /* Add an item to a proto_tree, using the text label registered to that item;
2534    the item is extracted from the tvbuff handed to it. */
2535 static proto_item *
proto_tree_new_item(field_info * new_fi,proto_tree * tree,tvbuff_t * tvb,gint start,gint length,guint encoding)2536 proto_tree_new_item(field_info *new_fi, proto_tree *tree,
2537 		    tvbuff_t *tvb, gint start, gint length,
2538 		    guint encoding)
2539 {
2540 	proto_item *pi;
2541 	guint32	    value, n;
2542 	guint64	    value64;
2543 	ws_in4_addr ipv4_value;
2544 	float	    floatval;
2545 	double	    doubleval;
2546 	const char *stringval = NULL;
2547 	nstime_t    time_stamp;
2548 	gboolean    length_error;
2549 
2550 	switch (new_fi->hfinfo->type) {
2551 		case FT_NONE:
2552 			/* no value to set for FT_NONE */
2553 			break;
2554 
2555 		case FT_PROTOCOL:
2556 			proto_tree_set_protocol_tvb(new_fi, tvb, new_fi->hfinfo->name);
2557 			break;
2558 
2559 		case FT_BYTES:
2560 			proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
2561 			break;
2562 
2563 		case FT_UINT_BYTES:
2564 			n = get_uint_value(tree, tvb, start, length, encoding);
2565 			proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
2566 
2567 			/* Instead of calling proto_item_set_len(), since we don't yet
2568 			 * have a proto_item, we set the field_info's length ourselves. */
2569 			new_fi->length = n + length;
2570 			break;
2571 
2572 		case FT_BOOLEAN:
2573 			/*
2574 			 * Map all non-zero values to little-endian for
2575 			 * backwards compatibility.
2576 			 */
2577 			if (encoding)
2578 				encoding = ENC_LITTLE_ENDIAN;
2579 			proto_tree_set_boolean(new_fi,
2580 				get_uint64_value(tree, tvb, start, length, encoding));
2581 			break;
2582 
2583 		case FT_CHAR:
2584 		/* XXX - make these just FT_UINT? */
2585 		case FT_UINT8:
2586 		case FT_UINT16:
2587 		case FT_UINT24:
2588 		case FT_UINT32:
2589 			if (encoding & ENC_VARINT_PROTOBUF) {
2590 				new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN : length, &value64, encoding);
2591 				new_fi->flags |= FI_VARINT;
2592 				value = (guint32)value64;
2593 			} else if (encoding & ENC_VARINT_QUIC) {
2594 				new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN : length, &value64, encoding);
2595 				value = (guint32)value64;
2596 			} else if (encoding & ENC_VARINT_ZIGZAG) {
2597 				new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN : length, &value64, encoding);
2598 				new_fi->flags |= FI_VARINT;
2599 				value = (guint32)value64;
2600 			}
2601 			else {
2602 				/*
2603 				 * Map all non-zero values to little-endian for
2604 				 * backwards compatibility.
2605 				 */
2606 				if (encoding)
2607 					encoding = ENC_LITTLE_ENDIAN;
2608 
2609 				value = get_uint_value(tree, tvb, start, length, encoding);
2610 			}
2611 			proto_tree_set_uint(new_fi, value);
2612 			break;
2613 
2614 		case FT_UINT40:
2615 		case FT_UINT48:
2616 		case FT_UINT56:
2617 		case FT_UINT64:
2618 
2619 			if (encoding & ENC_VARINT_PROTOBUF) {
2620 				new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN : length, &value64, encoding);
2621 				new_fi->flags |= FI_VARINT;
2622 			} else if (encoding & ENC_VARINT_QUIC) {
2623 				new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN : length, &value64, encoding);
2624 			} else if (encoding & ENC_VARINT_ZIGZAG) {
2625 				new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN : length, &value64, encoding);
2626 				new_fi->flags |= FI_VARINT;
2627 			}
2628 			else {
2629 				/*
2630 				 * Map all other non-zero values to little-endian for
2631 				 * backwards compatibility.
2632 				 */
2633 				if (encoding)
2634 					encoding = ENC_LITTLE_ENDIAN;
2635 
2636 				value64 = get_uint64_value(tree, tvb, start, length, encoding);
2637 			}
2638 			proto_tree_set_uint64(new_fi, value64);
2639 			break;
2640 
2641 		/* XXX - make these just FT_INT? */
2642 		case FT_INT8:
2643 		case FT_INT16:
2644 		case FT_INT24:
2645 		case FT_INT32:
2646 			/*
2647 			 * Map all non-zero values to little-endian for
2648 			 * backwards compatibility.
2649 			 */
2650 			if (encoding)
2651 				encoding = ENC_LITTLE_ENDIAN;
2652 			proto_tree_set_int(new_fi,
2653 				get_int_value(tree, tvb, start, length, encoding));
2654 			break;
2655 
2656 		case FT_INT40:
2657 		case FT_INT48:
2658 		case FT_INT56:
2659 		case FT_INT64:
2660 			/*
2661 			 * Map all non-zero values to little-endian for
2662 			 * backwards compatibility.
2663 			 */
2664 			if (encoding)
2665 				encoding = ENC_LITTLE_ENDIAN;
2666 			proto_tree_set_int64(new_fi,
2667 				get_int64_value(tree, tvb, start, length, encoding));
2668 			break;
2669 
2670 		case FT_IPv4:
2671 			/*
2672 			 * Map all non-zero values to little-endian for
2673 			 * backwards compatibility.
2674 			 */
2675 			if (encoding)
2676 				encoding = ENC_LITTLE_ENDIAN;
2677 			if (length != FT_IPv4_LEN) {
2678 				length_error = length < FT_IPv4_LEN ? TRUE : FALSE;
2679 				report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
2680 			}
2681 			ipv4_value = tvb_get_ipv4(tvb, start);
2682 			/*
2683 			 * NOTE: to support code written when
2684 			 * proto_tree_add_item() took a gboolean as its
2685 			 * last argument, with FALSE meaning "big-endian"
2686 			 * and TRUE meaning "little-endian", we treat any
2687 			 * non-zero value of "encoding" as meaning
2688 			 * "little-endian".
2689 			 */
2690 			proto_tree_set_ipv4(new_fi, encoding ? GUINT32_SWAP_LE_BE(ipv4_value) : ipv4_value);
2691 			break;
2692 
2693 		case FT_IPXNET:
2694 			if (length != FT_IPXNET_LEN) {
2695 				length_error = length < FT_IPXNET_LEN ? TRUE : FALSE;
2696 				report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
2697 			}
2698 			proto_tree_set_ipxnet(new_fi,
2699 				get_uint_value(tree, tvb, start, FT_IPXNET_LEN, ENC_BIG_ENDIAN));
2700 			break;
2701 
2702 		case FT_IPv6:
2703 			if (length != FT_IPv6_LEN) {
2704 				length_error = length < FT_IPv6_LEN ? TRUE : FALSE;
2705 				report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
2706 			}
2707 			proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
2708 			break;
2709 
2710 		case FT_FCWWN:
2711 			if (length != FT_FCWWN_LEN) {
2712 				length_error = length < FT_FCWWN_LEN ? TRUE : FALSE;
2713 				report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
2714 			}
2715 			proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
2716 			break;
2717 
2718 		case FT_AX25:
2719 			if (length != 7) {
2720 				length_error = length < 7 ? TRUE : FALSE;
2721 				report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
2722 			}
2723 			proto_tree_set_ax25_tvb(new_fi, tvb, start);
2724 			break;
2725 
2726 		case FT_VINES:
2727 			if (length != VINES_ADDR_LEN) {
2728 				length_error = length < VINES_ADDR_LEN ? TRUE : FALSE;
2729 				report_type_length_mismatch(tree, "a Vines address", length, length_error);
2730 			}
2731 			proto_tree_set_vines_tvb(new_fi, tvb, start);
2732 			break;
2733 
2734 		case FT_ETHER:
2735 			if (length != FT_ETHER_LEN) {
2736 				length_error = length < FT_ETHER_LEN ? TRUE : FALSE;
2737 				report_type_length_mismatch(tree, "a MAC address", length, length_error);
2738 			}
2739 			proto_tree_set_ether_tvb(new_fi, tvb, start);
2740 			break;
2741 
2742 		case FT_EUI64:
2743 			/*
2744 			 * Map all non-zero values to little-endian for
2745 			 * backwards compatibility.
2746 			 */
2747 			if (encoding)
2748 				encoding = ENC_LITTLE_ENDIAN;
2749 			if (length != FT_EUI64_LEN) {
2750 				length_error = length < FT_EUI64_LEN ? TRUE : FALSE;
2751 				report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
2752 			}
2753 			proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
2754 			break;
2755 		case FT_GUID:
2756 			/*
2757 			 * Map all non-zero values to little-endian for
2758 			 * backwards compatibility.
2759 			 */
2760 			if (encoding)
2761 				encoding = ENC_LITTLE_ENDIAN;
2762 			if (length != FT_GUID_LEN) {
2763 				length_error = length < FT_GUID_LEN ? TRUE : FALSE;
2764 				report_type_length_mismatch(tree, "a GUID", length, length_error);
2765 			}
2766 			proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
2767 			break;
2768 
2769 		case FT_OID:
2770 		case FT_REL_OID:
2771 			proto_tree_set_oid_tvb(new_fi, tvb, start, length);
2772 			break;
2773 
2774 		case FT_SYSTEM_ID:
2775 			proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
2776 			break;
2777 
2778 		case FT_FLOAT:
2779 			/*
2780 			 * NOTE: to support code written when
2781 			 * proto_tree_add_item() took a gboolean as its
2782 			 * last argument, with FALSE meaning "big-endian"
2783 			 * and TRUE meaning "little-endian", we treat any
2784 			 * non-zero value of "encoding" as meaning
2785 			 * "little-endian".
2786 			 *
2787 			 * At some point in the future, we might
2788 			 * support non-IEEE-binary floating-point
2789 			 * formats in the encoding as well
2790 			 * (IEEE decimal, System/3x0, VAX).
2791 			 */
2792 			if (encoding)
2793 				encoding = ENC_LITTLE_ENDIAN;
2794 			if (length != 4) {
2795 				length_error = length < 4 ? TRUE : FALSE;
2796 				report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
2797 			}
2798 			if (encoding)
2799 				floatval = tvb_get_letohieee_float(tvb, start);
2800 			else
2801 				floatval = tvb_get_ntohieee_float(tvb, start);
2802 			proto_tree_set_float(new_fi, floatval);
2803 			break;
2804 
2805 		case FT_DOUBLE:
2806 			/*
2807 			 * NOTE: to support code written when
2808 			 * proto_tree_add_item() took a gboolean as its
2809 			 * last argument, with FALSE meaning "big-endian"
2810 			 * and TRUE meaning "little-endian", we treat any
2811 			 * non-zero value of "encoding" as meaning
2812 			 * "little-endian".
2813 			 *
2814 			 * At some point in the future, we might
2815 			 * support non-IEEE-binary floating-point
2816 			 * formats in the encoding as well
2817 			 * (IEEE decimal, System/3x0, VAX).
2818 			 */
2819 			if (encoding == TRUE)
2820 				encoding = ENC_LITTLE_ENDIAN;
2821 			if (length != 8) {
2822 				length_error = length < 8 ? TRUE : FALSE;
2823 				report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
2824 			}
2825 			if (encoding)
2826 				doubleval = tvb_get_letohieee_double(tvb, start);
2827 			else
2828 				doubleval = tvb_get_ntohieee_double(tvb, start);
2829 			proto_tree_set_double(new_fi, doubleval);
2830 			break;
2831 
2832 		case FT_STRING:
2833 			stringval = get_string_value(PNODE_POOL(tree),
2834 			    tvb, start, length, &length, encoding);
2835 			proto_tree_set_string(new_fi, stringval);
2836 
2837 			/* Instead of calling proto_item_set_len(), since we
2838 			 * don't yet have a proto_item, we set the
2839 			 * field_info's length ourselves.
2840 			 *
2841 			 * XXX - our caller can't use that length to
2842 			 * advance an offset unless they arrange that
2843 			 * there always be a protocol tree into which
2844 			 * we're putting this item.
2845 			 */
2846 			new_fi->length = length;
2847 			break;
2848 
2849 		case FT_STRINGZ:
2850 			stringval = get_stringz_value(PNODE_POOL(tree),
2851 			    tree, tvb, start, length, &length, encoding);
2852 			proto_tree_set_string(new_fi, stringval);
2853 
2854 			/* Instead of calling proto_item_set_len(),
2855 			 * since we don't yet have a proto_item, we
2856 			 * set the field_info's length ourselves.
2857 			 *
2858 			 * XXX - our caller can't use that length to
2859 			 * advance an offset unless they arrange that
2860 			 * there always be a protocol tree into which
2861 			 * we're putting this item.
2862 			 */
2863 			new_fi->length = length;
2864 			break;
2865 
2866 		case FT_UINT_STRING:
2867 			/*
2868 			 * NOTE: to support code written when
2869 			 * proto_tree_add_item() took a gboolean as its
2870 			 * last argument, with FALSE meaning "big-endian"
2871 			 * and TRUE meaning "little-endian", if the
2872 			 * encoding value is TRUE, treat that as
2873 			 * ASCII with a little-endian length.
2874 			 *
2875 			 * This won't work for code that passes
2876 			 * arbitrary non-zero values; that code
2877 			 * will need to be fixed.
2878 			 */
2879 			if (encoding == TRUE)
2880 				encoding = ENC_ASCII|ENC_LITTLE_ENDIAN;
2881 			stringval = get_uint_string_value(PNODE_POOL(tree),
2882 			    tree, tvb, start, length, &length, encoding);
2883 			proto_tree_set_string(new_fi, stringval);
2884 
2885 			/* Instead of calling proto_item_set_len(), since we
2886 			 * don't yet have a proto_item, we set the
2887 			 * field_info's length ourselves.
2888 			 *
2889 			 * XXX - our caller can't use that length to
2890 			 * advance an offset unless they arrange that
2891 			 * there always be a protocol tree into which
2892 			 * we're putting this item.
2893 			 */
2894 			new_fi->length = length;
2895 			break;
2896 
2897 		case FT_STRINGZPAD:
2898 			stringval = get_stringzpad_value(PNODE_POOL(tree),
2899 			    tvb, start, length, &length, encoding);
2900 			proto_tree_set_string(new_fi, stringval);
2901 
2902 			/* Instead of calling proto_item_set_len(), since we
2903 			 * don't yet have a proto_item, we set the
2904 			 * field_info's length ourselves.
2905 			 *
2906 			 * XXX - our caller can't use that length to
2907 			 * advance an offset unless they arrange that
2908 			 * there always be a protocol tree into which
2909 			 * we're putting this item.
2910 			 */
2911 			new_fi->length = length;
2912 			break;
2913 
2914 		case FT_STRINGZTRUNC:
2915 			stringval = get_stringztrunc_value(PNODE_POOL(tree),
2916 			    tvb, start, length, &length, encoding);
2917 			proto_tree_set_string(new_fi, stringval);
2918 
2919 			/* Instead of calling proto_item_set_len(), since we
2920 			 * don't yet have a proto_item, we set the
2921 			 * field_info's length ourselves.
2922 			 *
2923 			 * XXX - our caller can't use that length to
2924 			 * advance an offset unless they arrange that
2925 			 * there always be a protocol tree into which
2926 			 * we're putting this item.
2927 			 */
2928 			new_fi->length = length;
2929 			break;
2930 
2931 		case FT_ABSOLUTE_TIME:
2932 			/*
2933 			 * Absolute times can be in any of a number of
2934 			 * formats, and they can be big-endian or
2935 			 * little-endian.
2936 			 *
2937 			 * Historically FT_TIMEs were only timespecs;
2938 			 * the only question was whether they were stored
2939 			 * in big- or little-endian format.
2940 			 *
2941 			 * For backwards compatibility, we interpret an
2942 			 * encoding of 1 as meaning "little-endian timespec",
2943 			 * so that passing TRUE is interpreted as that.
2944 			 */
2945 			if (encoding == TRUE)
2946 				encoding = ENC_TIME_SECS_NSECS|ENC_LITTLE_ENDIAN;
2947 
2948 			get_time_value(tree, tvb, start, length, encoding, &time_stamp, FALSE);
2949 
2950 			proto_tree_set_time(new_fi, &time_stamp);
2951 			break;
2952 
2953 		case FT_RELATIVE_TIME:
2954 			/*
2955 			 * Relative times can be in any of a number of
2956 			 * formats, and they can be big-endian or
2957 			 * little-endian.
2958 			 *
2959 			 * Historically FT_TIMEs were only timespecs;
2960 			 * the only question was whether they were stored
2961 			 * in big- or little-endian format.
2962 			 *
2963 			 * For backwards compatibility, we interpret an
2964 			 * encoding of 1 as meaning "little-endian timespec",
2965 			 * so that passing TRUE is interpreted as that.
2966 			 */
2967 			if (encoding == TRUE)
2968 				encoding = ENC_TIME_SECS_NSECS|ENC_LITTLE_ENDIAN;
2969 
2970 			get_time_value(tree, tvb, start, length, encoding, &time_stamp, TRUE);
2971 
2972 			proto_tree_set_time(new_fi, &time_stamp);
2973 			break;
2974 		case FT_IEEE_11073_SFLOAT:
2975 			if (encoding)
2976 				encoding = ENC_LITTLE_ENDIAN;
2977 			if (length != 2) {
2978 				length_error = length < 2 ? TRUE : FALSE;
2979 				report_type_length_mismatch(tree, "a IEEE 11073 SFLOAT", length, length_error);
2980 			}
2981 
2982 			fvalue_set_uinteger(&new_fi->value, tvb_get_guint16(tvb, start, encoding));
2983 
2984 			break;
2985 		case FT_IEEE_11073_FLOAT:
2986 			if (encoding)
2987 				encoding = ENC_LITTLE_ENDIAN;
2988 			if (length != 4) {
2989 				length_error = length < 4 ? TRUE : FALSE;
2990 				report_type_length_mismatch(tree, "a IEEE 11073 FLOAT", length, length_error);
2991 			}
2992 
2993 			break;
2994 		default:
2995 			REPORT_DISSECTOR_BUG("field %s is of unknown type %d (%s)",
2996 					     new_fi->hfinfo->abbrev,
2997 					     new_fi->hfinfo->type,
2998 					     ftype_name(new_fi->hfinfo->type));
2999 			break;
3000 	}
3001 	FI_SET_FLAG(new_fi, (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN);
3002 
3003 	/* Don't add new node to proto_tree until now so that any exceptions
3004 	 * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
3005 	/* XXX. wouldn't be better to add this item to tree, with some special flag (FI_EXCEPTION?)
3006 	 *      to know which item caused exception? */
3007 	pi = proto_tree_add_node(tree, new_fi);
3008 
3009 	switch (new_fi->hfinfo->type) {
3010 
3011 	case FT_STRING:
3012 		detect_trailing_stray_characters(encoding, stringval, length, pi);
3013 		break;
3014 
3015 	default:
3016 		break;
3017 	}
3018 
3019 	return pi;
3020 }
3021 
3022 proto_item *
proto_tree_add_item_ret_int(proto_tree * tree,int hfindex,tvbuff_t * tvb,const gint start,gint length,const guint encoding,gint32 * retval)3023 proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3024                             const gint start, gint length,
3025                             const guint encoding, gint32 *retval)
3026 {
3027 	header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3028 	field_info	  *new_fi;
3029 	gint32		   value;
3030 
3031 	DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3032 
3033 	switch (hfinfo->type) {
3034 	case FT_INT8:
3035 	case FT_INT16:
3036 	case FT_INT24:
3037 	case FT_INT32:
3038 		break;
3039 	case FT_INT64:
3040 		REPORT_DISSECTOR_BUG("64-bit signed integer field %s used with proto_tree_add_item_ret_int()",
3041 		    hfinfo->abbrev);
3042 	default:
3043 		REPORT_DISSECTOR_BUG("Non-signed-integer field %s used with proto_tree_add_item_ret_int()",
3044 		    hfinfo->abbrev);
3045 	}
3046 
3047 	/* length validation for native number encoding caught by get_uint_value() */
3048 	/* length has to be -1 or > 0 regardless of encoding */
3049 	if (length < -1 || length == 0)
3050 		REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_int",
3051 			length);
3052 
3053 	if (encoding & ENC_STRING) {
3054 		REPORT_DISSECTOR_BUG("wrong encoding");
3055 	}
3056 	/* I believe it's ok if this is called with a NULL tree */
3057 	value = get_int_value(tree, tvb, start, length, encoding);
3058 
3059 	if (retval) {
3060 		gint no_of_bits;
3061 		*retval = value;
3062 		if (hfinfo->bitmask) {
3063 			/* Mask out irrelevant portions */
3064 			*retval &= (guint32)(hfinfo->bitmask);
3065 			/* Shift bits */
3066 			*retval >>= hfinfo_bitshift(hfinfo);
3067 		}
3068 		no_of_bits = ws_count_ones(hfinfo->bitmask);
3069 		*retval = ws_sign_ext32(*retval, no_of_bits);
3070 	}
3071 
3072 	CHECK_FOR_NULL_TREE(tree);
3073 
3074 	TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3075 
3076 	new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3077 
3078 	proto_tree_set_int(new_fi, value);
3079 
3080 	new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
3081 
3082 	return proto_tree_add_node(tree, new_fi);
3083 }
3084 
3085 proto_item *
proto_tree_add_item_ret_uint(proto_tree * tree,int hfindex,tvbuff_t * tvb,const gint start,gint length,const guint encoding,guint32 * retval)3086 proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3087                              const gint start, gint length,
3088                              const guint encoding, guint32 *retval)
3089 {
3090 	header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3091 	field_info	  *new_fi;
3092 	guint32		   value;
3093 
3094 	DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3095 
3096 	switch (hfinfo->type) {
3097 	case FT_CHAR:
3098 	case FT_UINT8:
3099 	case FT_UINT16:
3100 	case FT_UINT24:
3101 	case FT_UINT32:
3102 		break;
3103 	default:
3104 		REPORT_DISSECTOR_BUG("field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32",
3105 		    hfinfo->abbrev);
3106 	}
3107 
3108 	/* length validation for native number encoding caught by get_uint_value() */
3109 	/* length has to be -1 or > 0 regardless of encoding */
3110 	if (length < -1 || length == 0)
3111 		REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_uint",
3112 			length);
3113 
3114 	if (encoding & ENC_STRING) {
3115 		REPORT_DISSECTOR_BUG("wrong encoding");
3116 	}
3117 	/* I believe it's ok if this is called with a NULL tree */
3118 	/* XXX - modify if we ever support EBCDIC FT_CHAR */
3119 	if (encoding & (ENC_VARIANT_MASK)) {
3120 		guint64 temp64;
3121 		tvb_get_varint(tvb, start, length, &temp64, encoding);
3122 		value = (guint32)temp64;
3123 	} else {
3124 		value = get_uint_value(tree, tvb, start, length, encoding);
3125 	}
3126 
3127 	if (retval) {
3128 		*retval = value;
3129 		if (hfinfo->bitmask) {
3130 			/* Mask out irrelevant portions */
3131 			*retval &= (guint32)(hfinfo->bitmask);
3132 			/* Shift bits */
3133 			*retval >>= hfinfo_bitshift(hfinfo);
3134 		}
3135 	}
3136 
3137 	CHECK_FOR_NULL_TREE(tree);
3138 
3139 	TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3140 
3141 	new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3142 
3143 	proto_tree_set_uint(new_fi, value);
3144 
3145 	new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
3146 	if (encoding & (ENC_VARINT_PROTOBUF|ENC_VARINT_ZIGZAG)) {
3147 		new_fi->flags |= FI_VARINT;
3148 	}
3149 	return proto_tree_add_node(tree, new_fi);
3150 }
3151 
3152 /* Gets data from tvbuff, adds it to proto_tree, increments offset,
3153  * and returns proto_item* and uint value retreived*/
3154 proto_item *
ptvcursor_add_ret_uint(ptvcursor_t * ptvc,int hfindex,gint length,const guint encoding,guint32 * retval)3155 ptvcursor_add_ret_uint(ptvcursor_t *ptvc, int hfindex, gint length,
3156 	      const guint encoding, guint32 *retval)
3157 {
3158 	field_info	  *new_fi;
3159 	header_field_info *hfinfo;
3160 	gint		   item_length;
3161 	int		   offset;
3162 	guint32		   value;
3163 
3164 	offset = ptvc->offset;
3165 	PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3166 
3167 	switch (hfinfo->type) {
3168 	case FT_CHAR:
3169 	case FT_UINT8:
3170 	case FT_UINT16:
3171 	case FT_UINT24:
3172 	case FT_UINT32:
3173 		break;
3174 	default:
3175 		REPORT_DISSECTOR_BUG("field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32",
3176 		    hfinfo->abbrev);
3177 	}
3178 
3179 	get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3180 	test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3181 
3182 	/* I believe it's ok if this is called with a NULL tree */
3183 	/* XXX - modify if we ever support EBCDIC FT_CHAR */
3184 	value = get_uint_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3185 
3186 	if (retval) {
3187 		*retval = value;
3188 		if (hfinfo->bitmask) {
3189 			/* Mask out irrelevant portions */
3190 			*retval &= (guint32)(hfinfo->bitmask);
3191 			/* Shift bits */
3192 			*retval >>= hfinfo_bitshift(hfinfo);
3193 		}
3194 	}
3195 
3196 	ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
3197 	    item_length, encoding);
3198 
3199 	CHECK_FOR_NULL_TREE(ptvc->tree);
3200 
3201 	/* Coast clear. Try and fake it */
3202 	TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo);
3203 
3204 	new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3205 
3206 	return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3207 		offset, length, encoding);
3208 }
3209 
3210 /* Gets data from tvbuff, adds it to proto_tree, increments offset,
3211  * and returns proto_item* and int value retreived*/
3212 proto_item *
ptvcursor_add_ret_int(ptvcursor_t * ptvc,int hfindex,gint length,const guint encoding,gint32 * retval)3213 ptvcursor_add_ret_int(ptvcursor_t *ptvc, int hfindex, gint length,
3214 	      const guint encoding, gint32 *retval)
3215 {
3216 	field_info	  *new_fi;
3217 	header_field_info *hfinfo;
3218 	gint		   item_length;
3219 	int		   offset;
3220 	guint32		   value;
3221 
3222 	offset = ptvc->offset;
3223 	PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3224 
3225 	switch (hfinfo->type) {
3226 	case FT_INT8:
3227 	case FT_INT16:
3228 	case FT_INT24:
3229 	case FT_INT32:
3230 		break;
3231 	default:
3232 		REPORT_DISSECTOR_BUG("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32",
3233 		    hfinfo->abbrev);
3234 	}
3235 
3236 	get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3237 	test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3238 
3239 	/* I believe it's ok if this is called with a NULL tree */
3240 	/* XXX - modify if we ever support EBCDIC FT_CHAR */
3241 	value = get_int_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3242 
3243 	if (retval) {
3244 		gint no_of_bits;
3245 		*retval = value;
3246 		if (hfinfo->bitmask) {
3247 			/* Mask out irrelevant portions */
3248 			*retval &= (guint32)(hfinfo->bitmask);
3249 			/* Shift bits */
3250 			*retval >>= hfinfo_bitshift(hfinfo);
3251 		}
3252 		no_of_bits = ws_count_ones(hfinfo->bitmask);
3253 		*retval = ws_sign_ext32(*retval, no_of_bits);
3254 	}
3255 
3256 	ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
3257 	    item_length, encoding);
3258 
3259 	CHECK_FOR_NULL_TREE(ptvc->tree);
3260 
3261 	/* Coast clear. Try and fake it */
3262 	TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo);
3263 
3264 	new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3265 
3266 	return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3267 		offset, length, encoding);
3268 }
3269 
3270 /* Gets data from tvbuff, adds it to proto_tree, increments offset,
3271  * and returns proto_item* and string value retreived */
3272 proto_item*
ptvcursor_add_ret_string(ptvcursor_t * ptvc,int hf,gint length,const guint encoding,wmem_allocator_t * scope,const guint8 ** retval)3273 ptvcursor_add_ret_string(ptvcursor_t* ptvc, int hf, gint length, const guint encoding, wmem_allocator_t *scope, const guint8 **retval)
3274 {
3275 	header_field_info *hfinfo;
3276 	field_info		*new_fi;
3277 	const guint8	*value;
3278 	gint			item_length;
3279 	int				offset;
3280 
3281 	offset = ptvc->offset;
3282 
3283 	PROTO_REGISTRAR_GET_NTH(hf, hfinfo);
3284 
3285 	switch (hfinfo->type) {
3286 	case FT_STRING:
3287 		value = get_string_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3288 		break;
3289 	case FT_STRINGZ:
3290 		value = get_stringz_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3291 		break;
3292 	case FT_UINT_STRING:
3293 		value = get_uint_string_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3294 		break;
3295 	case FT_STRINGZPAD:
3296 		value = get_stringzpad_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3297 		break;
3298 	case FT_STRINGZTRUNC:
3299 		value = get_stringztrunc_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3300 		break;
3301 	default:
3302 		REPORT_DISSECTOR_BUG("field %s is not of type FT_STRING, FT_STRINGZ, FT_UINT_STRING, FT_STRINGZPAD, or FT_STRINGZTRUNC",
3303 		    hfinfo->abbrev);
3304 	}
3305 
3306 	if (retval)
3307 		*retval = value;
3308 
3309 	ptvc->offset += item_length;
3310 
3311 	CHECK_FOR_NULL_TREE(ptvc->tree);
3312 
3313 	TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfinfo->id, hfinfo);
3314 
3315 	new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3316 
3317 	return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3318 		offset, length, encoding);
3319 }
3320 
3321 /* Gets data from tvbuff, adds it to proto_tree, increments offset,
3322  * and returns proto_item* and boolean value retreived */
3323 proto_item*
ptvcursor_add_ret_boolean(ptvcursor_t * ptvc,int hfindex,gint length,const guint encoding,gboolean * retval)3324 ptvcursor_add_ret_boolean(ptvcursor_t* ptvc, int hfindex, gint length, const guint encoding, gboolean *retval)
3325 {
3326 	header_field_info *hfinfo;
3327 	field_info		*new_fi;
3328 	gint			item_length;
3329 	int				offset;
3330 	guint64			value, bitval;
3331 
3332 	offset = ptvc->offset;
3333 	PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3334 
3335 	if (hfinfo->type != FT_BOOLEAN) {
3336 		REPORT_DISSECTOR_BUG("field %s is not of type FT_BOOLEAN",
3337 		    hfinfo->abbrev);
3338 	}
3339 
3340 	/* length validation for native number encoding caught by get_uint64_value() */
3341 	/* length has to be -1 or > 0 regardless of encoding */
3342 	if (length < -1 || length == 0)
3343 		REPORT_DISSECTOR_BUG("Invalid length %d passed to ptvcursor_add_ret_boolean",
3344 			length);
3345 
3346 	if (encoding & ENC_STRING) {
3347 		REPORT_DISSECTOR_BUG("wrong encoding");
3348 	}
3349 
3350 	get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3351 	test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3352 
3353 	/* I believe it's ok if this is called with a NULL tree */
3354 	value = get_uint64_value(ptvc->tree, ptvc->tvb, offset, length, encoding);
3355 
3356 	if (retval) {
3357 		bitval = value;
3358 		if (hfinfo->bitmask) {
3359 			/* Mask out irrelevant portions */
3360 			bitval &= hfinfo->bitmask;
3361 		}
3362 		*retval = (bitval != 0);
3363 	}
3364 
3365 	ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
3366 	    item_length, encoding);
3367 
3368 	CHECK_FOR_NULL_TREE(ptvc->tree);
3369 
3370 	TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfinfo->id, hfinfo);
3371 
3372 	new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3373 
3374 	return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3375 		offset, length, encoding);
3376 }
3377 
3378 proto_item *
proto_tree_add_item_ret_uint64(proto_tree * tree,int hfindex,tvbuff_t * tvb,const gint start,gint length,const guint encoding,guint64 * retval)3379 proto_tree_add_item_ret_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3380     const gint start, gint length, const guint encoding, guint64 *retval)
3381 {
3382 	header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3383 	field_info	  *new_fi;
3384 	guint64		   value;
3385 
3386 	DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3387 
3388 	switch (hfinfo->type) {
3389 	case FT_UINT40:
3390 	case FT_UINT48:
3391 	case FT_UINT56:
3392 	case FT_UINT64:
3393 		break;
3394 	default:
3395 		REPORT_DISSECTOR_BUG("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64",
3396 		    hfinfo->abbrev);
3397 	}
3398 
3399 	/* length validation for native number encoding caught by get_uint64_value() */
3400 	/* length has to be -1 or > 0 regardless of encoding */
3401 	if (length < -1 || length == 0)
3402 		REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_uint64",
3403 			length);
3404 
3405 	if (encoding & ENC_STRING) {
3406 		REPORT_DISSECTOR_BUG("wrong encoding");
3407 	}
3408 	/* I believe it's ok if this is called with a NULL tree */
3409 	if (encoding & (ENC_VARIANT_MASK)) {
3410 		tvb_get_varint(tvb, start, length, &value, encoding);
3411 	} else {
3412 		value = get_uint64_value(tree, tvb, start, length, encoding);
3413 	}
3414 
3415 	if (retval) {
3416 		*retval = value;
3417 		if (hfinfo->bitmask) {
3418 			/* Mask out irrelevant portions */
3419 			*retval &= hfinfo->bitmask;
3420 			/* Shift bits */
3421 			*retval >>= hfinfo_bitshift(hfinfo);
3422 		}
3423 	}
3424 
3425 	CHECK_FOR_NULL_TREE(tree);
3426 
3427 	TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3428 
3429 	new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3430 
3431 	proto_tree_set_uint64(new_fi, value);
3432 
3433 	new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
3434 	if (encoding & (ENC_VARINT_PROTOBUF|ENC_VARINT_ZIGZAG)) {
3435 		new_fi->flags |= FI_VARINT;
3436 	}
3437 
3438 	return proto_tree_add_node(tree, new_fi);
3439 }
3440 
3441 proto_item *
proto_tree_add_item_ret_int64(proto_tree * tree,int hfindex,tvbuff_t * tvb,const gint start,gint length,const guint encoding,gint64 * retval)3442 proto_tree_add_item_ret_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3443 	const gint start, gint length, const guint encoding, gint64 *retval)
3444 {
3445 	header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3446 	field_info	  *new_fi;
3447 	gint64		   value;
3448 
3449 	DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3450 
3451 	switch (hfinfo->type) {
3452 	case FT_INT40:
3453 	case FT_INT48:
3454 	case FT_INT56:
3455 	case FT_INT64:
3456 		break;
3457 	default:
3458 		REPORT_DISSECTOR_BUG("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64",
3459 			hfinfo->abbrev);
3460 	}
3461 
3462 	/* length validation for native number encoding caught by get_uint64_value() */
3463 	/* length has to be -1 or > 0 regardless of encoding */
3464 	if (length < -1 || length == 0)
3465 		REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_int64",
3466 			length);
3467 
3468 	if (encoding & ENC_STRING) {
3469 		REPORT_DISSECTOR_BUG("wrong encoding");
3470 	}
3471 	/* I believe it's ok if this is called with a NULL tree */
3472 	if (encoding & (ENC_VARIANT_MASK)) {
3473 		tvb_get_varint(tvb, start, length, &value, encoding);
3474 	}
3475 	else {
3476 		value = get_int64_value(tree, tvb, start, length, encoding);
3477 	}
3478 
3479 	if (retval) {
3480 		*retval = value;
3481 	}
3482 
3483 	CHECK_FOR_NULL_TREE(tree);
3484 
3485 	TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3486 
3487 	new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3488 
3489 	proto_tree_set_int64(new_fi, value);
3490 
3491 	new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
3492 	if (encoding & (ENC_VARINT_PROTOBUF | ENC_VARINT_ZIGZAG)) {
3493 		new_fi->flags |= FI_VARINT;
3494 	}
3495 
3496 	return proto_tree_add_node(tree, new_fi);
3497 }
3498 
3499 proto_item *
proto_tree_add_item_ret_varint(proto_tree * tree,int hfindex,tvbuff_t * tvb,const gint start,gint length,const guint encoding,guint64 * retval,gint * lenretval)3500 proto_tree_add_item_ret_varint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3501     const gint start, gint length, const guint encoding, guint64 *retval, gint *lenretval)
3502 {
3503 	header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3504 	field_info	*new_fi;
3505 	guint64		value;
3506 
3507 	DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3508 
3509 	if ((!IS_FT_INT(hfinfo->type)) && (!IS_FT_UINT(hfinfo->type))) {
3510 		REPORT_DISSECTOR_BUG("field %s is not of type FT_UINT or FT_INT",
3511 		    hfinfo->abbrev);
3512 	}
3513 
3514 	/* length validation for native number encoding caught by get_uint64_value() */
3515 	/* length has to be -1 or > 0 regardless of encoding */
3516 	if (length == 0)
3517 		REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_varint",
3518 			length);
3519 
3520 	if (encoding & ENC_STRING) {
3521 		REPORT_DISSECTOR_BUG("wrong encoding");
3522 	}
3523 
3524 	length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN : length, &value, encoding);
3525 
3526 	if (retval) {
3527 		*retval = value;
3528 		if (hfinfo->bitmask) {
3529 			/* Mask out irrelevant portions */
3530 			*retval &= hfinfo->bitmask;
3531 			/* Shift bits */
3532 			*retval >>= hfinfo_bitshift(hfinfo);
3533 		}
3534 	}
3535 
3536 	if (lenretval) {
3537 		*lenretval = length;
3538 	}
3539 
3540 	CHECK_FOR_NULL_TREE(tree);
3541 
3542 	TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3543 
3544 	new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3545 
3546 	proto_tree_set_uint64(new_fi, value);
3547 
3548 	new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
3549 	if (encoding & (ENC_VARINT_PROTOBUF|ENC_VARINT_ZIGZAG)) {
3550 		new_fi->flags |= FI_VARINT;
3551 	}
3552 
3553 	return proto_tree_add_node(tree, new_fi);
3554 
3555 }
3556 
3557 proto_item *
proto_tree_add_item_ret_boolean(proto_tree * tree,int hfindex,tvbuff_t * tvb,const gint start,gint length,const guint encoding,gboolean * retval)3558 proto_tree_add_item_ret_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3559                                 const gint start, gint length,
3560                                 const guint encoding, gboolean *retval)
3561 {
3562 	header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3563 	field_info	  *new_fi;
3564 	guint64		   value, bitval;
3565 
3566 	DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3567 
3568 	if (hfinfo->type != FT_BOOLEAN) {
3569 		REPORT_DISSECTOR_BUG("field %s is not of type FT_BOOLEAN",
3570 		    hfinfo->abbrev);
3571 	}
3572 
3573 	/* length validation for native number encoding caught by get_uint64_value() */
3574 	/* length has to be -1 or > 0 regardless of encoding */
3575 	if (length < -1 || length == 0)
3576 		REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_boolean",
3577 			length);
3578 
3579 	if (encoding & ENC_STRING) {
3580 		REPORT_DISSECTOR_BUG("wrong encoding");
3581 	}
3582 	/* I believe it's ok if this is called with a NULL tree */
3583 	value = get_uint64_value(tree, tvb, start, length, encoding);
3584 
3585 	if (retval) {
3586 		bitval = value;
3587 		if (hfinfo->bitmask) {
3588 			/* Mask out irrelevant portions */
3589 			bitval &= hfinfo->bitmask;
3590 		}
3591 		*retval = (bitval != 0);
3592 	}
3593 
3594 	CHECK_FOR_NULL_TREE(tree);
3595 
3596 	TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3597 
3598 	new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3599 
3600 	proto_tree_set_boolean(new_fi, value);
3601 
3602 	new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
3603 
3604 	return proto_tree_add_node(tree, new_fi);
3605 }
3606 
3607 proto_item *
proto_tree_add_item_ret_ipv4(proto_tree * tree,int hfindex,tvbuff_t * tvb,const gint start,gint length,const guint encoding,ws_in4_addr * retval)3608 proto_tree_add_item_ret_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3609                              const gint start, gint length,
3610                              const guint encoding, ws_in4_addr *retval)
3611 {
3612 	header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3613 	field_info	  *new_fi;
3614 	ws_in4_addr	   value;
3615 
3616 	DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3617 
3618 	switch (hfinfo->type) {
3619 	case FT_IPv4:
3620 		break;
3621 	default:
3622 		REPORT_DISSECTOR_BUG("field %s is not of type FT_IPv4",
3623 		    hfinfo->abbrev);
3624 	}
3625 
3626 	if (length != FT_IPv4_LEN)
3627 		REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_ipv4",
3628 			length);
3629 
3630 	if (encoding & (ENC_STRING | ENC_VARIANT_MASK | ENC_VARINT_PROTOBUF | ENC_VARINT_ZIGZAG)) {
3631 		REPORT_DISSECTOR_BUG("wrong encoding");
3632 	}
3633 
3634 	/*
3635 	 * NOTE: to support code written when proto_tree_add_item() took
3636 	 * a gboolean as its last argument, with FALSE meaning "big-endian"
3637 	 * and TRUE meaning "little-endian", we treat any non-zero value
3638 	 * of "encoding" as meaning "little-endian".
3639 	 */
3640 	value = tvb_get_ipv4(tvb, start);
3641 	if (encoding)
3642 		value = GUINT32_SWAP_LE_BE(value);
3643 
3644 	if (retval) {
3645 		*retval = value;
3646 	}
3647 
3648 	CHECK_FOR_NULL_TREE(tree);
3649 
3650 	TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3651 
3652 	new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3653 
3654 	proto_tree_set_ipv4(new_fi, value);
3655 
3656 	new_fi->flags |= encoding ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
3657 	return proto_tree_add_node(tree, new_fi);
3658 }
3659 
3660 proto_item *
proto_tree_add_item_ret_string_and_length(proto_tree * tree,int hfindex,tvbuff_t * tvb,const gint start,gint length,const guint encoding,wmem_allocator_t * scope,const guint8 ** retval,gint * lenretval)3661 proto_tree_add_item_ret_string_and_length(proto_tree *tree, int hfindex,
3662                                           tvbuff_t *tvb,
3663                                           const gint start, gint length,
3664                                           const guint encoding,
3665                                           wmem_allocator_t *scope,
3666                                           const guint8 **retval,
3667                                           gint *lenretval)
3668 {
3669 	proto_item *pi;
3670 	header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3671 	field_info	  *new_fi;
3672 	const guint8	  *value;
3673 
3674 	DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3675 
3676 	switch (hfinfo->type) {
3677 	case FT_STRING:
3678 		value = get_string_value(scope, tvb, start, length, lenretval, encoding);
3679 		break;
3680 	case FT_STRINGZ:
3681 		value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
3682 		break;
3683 	case FT_UINT_STRING:
3684 		value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
3685 		break;
3686 	case FT_STRINGZPAD:
3687 		value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
3688 		break;
3689 	case FT_STRINGZTRUNC:
3690 		value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
3691 		break;
3692 	default:
3693 		REPORT_DISSECTOR_BUG("field %s is not of type FT_STRING, FT_STRINGZ, FT_UINT_STRING, FT_STRINGZPAD, or FT_STRINGZTRUNC",
3694 		    hfinfo->abbrev);
3695 	}
3696 
3697 	if (retval)
3698 		*retval = value;
3699 
3700 	CHECK_FOR_NULL_TREE(tree);
3701 
3702 	TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3703 
3704 	new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
3705 
3706 	proto_tree_set_string(new_fi, value);
3707 
3708 	new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
3709 
3710 	pi = proto_tree_add_node(tree, new_fi);
3711 
3712 	switch (hfinfo->type) {
3713 
3714 	case FT_STRINGZ:
3715 	case FT_STRINGZPAD:
3716 	case FT_STRINGZTRUNC:
3717 	case FT_UINT_STRING:
3718 		break;
3719 
3720 	case FT_STRING:
3721 		detect_trailing_stray_characters(encoding, value, length, pi);
3722 		break;
3723 
3724 	default:
3725 		ws_assert_not_reached();
3726 	}
3727 
3728 	return pi;
3729 }
3730 
3731 proto_item *
proto_tree_add_item_ret_string(proto_tree * tree,int hfindex,tvbuff_t * tvb,const gint start,gint length,const guint encoding,wmem_allocator_t * scope,const guint8 ** retval)3732 proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3733                                const gint start, gint length,
3734                                const guint encoding, wmem_allocator_t *scope,
3735                                const guint8 **retval)
3736 {
3737 	return proto_tree_add_item_ret_string_and_length(tree, hfindex,
3738 	    tvb, start, length, encoding, scope, retval, &length);
3739 }
3740 
3741 proto_item *
proto_tree_add_item_ret_display_string_and_length(proto_tree * tree,int hfindex,tvbuff_t * tvb,const gint start,gint length,const guint encoding,wmem_allocator_t * scope,char ** retval,gint * lenretval)3742 proto_tree_add_item_ret_display_string_and_length(proto_tree *tree, int hfindex,
3743                                                   tvbuff_t *tvb,
3744                                                   const gint start, gint length,
3745                                                   const guint encoding,
3746                                                   wmem_allocator_t *scope,
3747                                                   char **retval,
3748                                                   gint *lenretval)
3749 {
3750 	proto_item *pi;
3751 	header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3752 	field_info	  *new_fi;
3753 	const guint8	  *value;
3754 	guint32		   n = 0;
3755 
3756 	DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3757 
3758 	switch (hfinfo->type) {
3759 	case FT_STRING:
3760 		value = get_string_value(scope, tvb, start, length, lenretval, encoding);
3761 		*retval = hfinfo_format_text(scope, hfinfo, value);
3762 		break;
3763 	case FT_STRINGZ:
3764 		value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
3765 		*retval = hfinfo_format_text(scope, hfinfo, value);
3766 		break;
3767 	case FT_UINT_STRING:
3768 		value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
3769 		*retval = hfinfo_format_text(scope, hfinfo, value);
3770 		break;
3771 	case FT_STRINGZPAD:
3772 		value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
3773 		*retval = hfinfo_format_text(scope, hfinfo, value);
3774 		break;
3775 	case FT_STRINGZTRUNC:
3776 		value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
3777 		*retval = hfinfo_format_text(scope, hfinfo, value);
3778 		break;
3779 	case FT_BYTES:
3780 		value = tvb_get_ptr(tvb, start, length);
3781 		*retval = hfinfo_format_bytes(scope, hfinfo, value, length);
3782 		*lenretval = length;
3783 		break;
3784 	case FT_UINT_BYTES:
3785 		n = get_uint_value(tree, tvb, start, length, encoding);
3786 		value = tvb_get_ptr(tvb, start + length, n);
3787 		*retval = hfinfo_format_bytes(scope, hfinfo, value, n);
3788 		*lenretval = length + n;
3789 		break;
3790 	default:
3791 		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",
3792 		    hfinfo->abbrev);
3793 	}
3794 
3795 	CHECK_FOR_NULL_TREE(tree);
3796 
3797 	TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3798 
3799 	new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
3800 
3801 	switch (hfinfo->type) {
3802 
3803 	case FT_STRING:
3804 	case FT_STRINGZ:
3805 	case FT_UINT_STRING:
3806 	case FT_STRINGZPAD:
3807 	case FT_STRINGZTRUNC:
3808 		proto_tree_set_string(new_fi, value);
3809 		break;
3810 
3811 	case FT_BYTES:
3812 		proto_tree_set_bytes(new_fi, value, length);
3813 		break;
3814 
3815 	case FT_UINT_BYTES:
3816 		proto_tree_set_bytes(new_fi, value, n);
3817 		break;
3818 
3819 	default:
3820 		ws_assert_not_reached();
3821 	}
3822 
3823 	new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
3824 
3825 	pi = proto_tree_add_node(tree, new_fi);
3826 
3827 	switch (hfinfo->type) {
3828 
3829 	case FT_STRINGZ:
3830 	case FT_STRINGZPAD:
3831 	case FT_STRINGZTRUNC:
3832 	case FT_UINT_STRING:
3833 		break;
3834 
3835 	case FT_STRING:
3836 		detect_trailing_stray_characters(encoding, value, length, pi);
3837 		break;
3838 
3839 	case FT_BYTES:
3840 	case FT_UINT_BYTES:
3841 		break;
3842 
3843 	default:
3844 		ws_assert_not_reached();
3845 	}
3846 
3847 	return pi;
3848 }
3849 
3850 proto_item *
proto_tree_add_item_ret_display_string(proto_tree * tree,int hfindex,tvbuff_t * tvb,const gint start,gint length,const guint encoding,wmem_allocator_t * scope,char ** retval)3851 proto_tree_add_item_ret_display_string(proto_tree *tree, int hfindex,
3852                                        tvbuff_t *tvb,
3853                                        const gint start, gint length,
3854                                        const guint encoding,
3855                                        wmem_allocator_t *scope,
3856                                        char **retval)
3857 {
3858 	return proto_tree_add_item_ret_display_string_and_length(tree, hfindex,
3859 	    tvb, start, length, encoding, scope, retval, &length);
3860 }
3861 
3862 proto_item *
proto_tree_add_item_ret_time_string(proto_tree * tree,int hfindex,tvbuff_t * tvb,const gint start,gint length,const guint encoding,wmem_allocator_t * scope,char ** retval)3863 proto_tree_add_item_ret_time_string(proto_tree *tree, int hfindex,
3864 	tvbuff_t *tvb,
3865 	const gint start, gint length, const guint encoding,
3866 	wmem_allocator_t *scope, char **retval)
3867 {
3868 	header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3869 	field_info	  *new_fi;
3870 	nstime_t    time_stamp;
3871 
3872 	DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3873 
3874 	switch (hfinfo->type) {
3875 	case FT_ABSOLUTE_TIME:
3876 		get_time_value(tree, tvb, start, length, encoding, &time_stamp, FALSE);
3877 		*retval = abs_time_to_str(scope, &time_stamp, (absolute_time_display_e)hfinfo->display, TRUE);
3878 		break;
3879 	case FT_RELATIVE_TIME:
3880 		get_time_value(tree, tvb, start, length, encoding, &time_stamp, TRUE);
3881 		*retval = rel_time_to_secs_str(scope, &time_stamp);
3882 		break;
3883 	default:
3884 		REPORT_DISSECTOR_BUG("field %s is not of type FT_ABSOLUTE_TIME or FT_RELATIVE_TIME",
3885 			hfinfo->abbrev);
3886 	}
3887 
3888 	CHECK_FOR_NULL_TREE(tree);
3889 
3890 	TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3891 
3892 	new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3893 
3894 	switch (hfinfo->type) {
3895 
3896 	case FT_ABSOLUTE_TIME:
3897 	case FT_RELATIVE_TIME:
3898 		proto_tree_set_time(new_fi, &time_stamp);
3899 		break;
3900 	default:
3901 		ws_assert_not_reached();
3902 	}
3903 
3904 	new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
3905 
3906 	return proto_tree_add_node(tree, new_fi);
3907 }
3908 
3909 /* Gets data from tvbuff, adds it to proto_tree, increments offset,
3910    and returns proto_item* */
3911 proto_item *
ptvcursor_add(ptvcursor_t * ptvc,int hfindex,gint length,const guint encoding)3912 ptvcursor_add(ptvcursor_t *ptvc, int hfindex, gint length,
3913 	      const guint encoding)
3914 {
3915 	field_info	  *new_fi;
3916 	header_field_info *hfinfo;
3917 	gint		   item_length;
3918 	int		   offset;
3919 
3920 	offset = ptvc->offset;
3921 	PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3922 	get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3923 	test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3924 
3925 	ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
3926 	    item_length, encoding);
3927 
3928 	CHECK_FOR_NULL_TREE(ptvc->tree);
3929 
3930 	/* Coast clear. Try and fake it */
3931 	TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo);
3932 
3933 	new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3934 
3935 	return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3936 		offset, length, encoding);
3937 }
3938 
3939 /* Add an item to a proto_tree, using the text label registered to that item;
3940    the item is extracted from the tvbuff handed to it. */
3941 proto_item *
proto_tree_add_item_new(proto_tree * tree,header_field_info * hfinfo,tvbuff_t * tvb,const gint start,gint length,const guint encoding)3942 proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
3943 			const gint start, gint length, const guint encoding)
3944 {
3945 	field_info        *new_fi;
3946 	gint		  item_length;
3947 
3948 	DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3949 
3950 	get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
3951 	test_length(hfinfo, tvb, start, item_length, encoding);
3952 
3953 	CHECK_FOR_NULL_TREE(tree);
3954 
3955 	TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3956 
3957 	new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
3958 
3959 	return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
3960 }
3961 
3962 proto_item *
proto_tree_add_item(proto_tree * tree,int hfindex,tvbuff_t * tvb,const gint start,gint length,const guint encoding)3963 proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3964 		    const gint start, gint length, const guint encoding)
3965 {
3966 	register header_field_info *hfinfo;
3967 
3968 	PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3969 	return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
3970 }
3971 
3972 /* Add an item to a proto_tree, using the text label registered to that item;
3973    the item is extracted from the tvbuff handed to it.
3974 
3975    Return the length of the item through the pointer. */
3976 proto_item *
proto_tree_add_item_new_ret_length(proto_tree * tree,header_field_info * hfinfo,tvbuff_t * tvb,const gint start,gint length,const guint encoding,gint * lenretval)3977 proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
3978 				   tvbuff_t *tvb, const gint start,
3979 				   gint length, const guint encoding,
3980 				   gint *lenretval)
3981 {
3982 	field_info        *new_fi;
3983 	gint		  item_length;
3984 	proto_item	 *item;
3985 
3986 	DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3987 
3988 	get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
3989 	test_length(hfinfo, tvb, start, item_length, encoding);
3990 
3991 	if (!tree) {
3992 		/*
3993 		 * We need to get the correct item length here.
3994 		 * That's normally done by proto_tree_new_item(),
3995 		 * but we won't be calling it.
3996 		 */
3997 		*lenretval = get_full_length(hfinfo, tvb, start, length,
3998 		    item_length, encoding);
3999 		return NULL;
4000 	}
4001 
4002 	TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfinfo->id, hfinfo, {
4003 		/*
4004 		 * Even if the tree item is not referenced (and thus faked),
4005 		 * the caller must still be informed of the actual length.
4006 		 */
4007 		*lenretval = get_full_length(hfinfo, tvb, start, length,
4008 		    item_length, encoding);
4009 	});
4010 
4011 	new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4012 
4013 	item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4014 	*lenretval = new_fi->length;
4015 	return item;
4016 }
4017 
4018 proto_item *
proto_tree_add_item_ret_length(proto_tree * tree,int hfindex,tvbuff_t * tvb,const gint start,gint length,const guint encoding,gint * lenretval)4019 proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4020 			       const gint start, gint length,
4021 			       const guint encoding, gint *lenretval)
4022 {
4023 	register header_field_info *hfinfo;
4024 
4025 	PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
4026 	return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, lenretval);
4027 }
4028 
4029 /* which FT_ types can use proto_tree_add_bytes_item() */
4030 static inline gboolean
validate_proto_tree_add_bytes_ftype(const enum ftenum type)4031 validate_proto_tree_add_bytes_ftype(const enum ftenum type)
4032 {
4033 	return (type == FT_BYTES      ||
4034 		type == FT_UINT_BYTES ||
4035 		type == FT_OID        ||
4036 		type == FT_REL_OID    ||
4037 		type == FT_SYSTEM_ID  );
4038 }
4039 
4040 /* Note: this does no validation that the byte array of an FT_OID or
4041    FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
4042    so I think it's ok to continue not validating it?
4043  */
4044 proto_item *
proto_tree_add_bytes_item(proto_tree * tree,int hfindex,tvbuff_t * tvb,const gint start,gint length,const guint encoding,GByteArray * retval,gint * endoff,gint * err)4045 proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4046 			   const gint start, gint length, const guint encoding,
4047 			   GByteArray *retval, gint *endoff, gint *err)
4048 {
4049 	field_info	  *new_fi;
4050 	GByteArray	  *bytes = retval;
4051 	GByteArray	  *created_bytes = NULL;
4052 	gint		   saved_err = 0;
4053 	guint32		   n = 0;
4054 	header_field_info *hfinfo;
4055 	gboolean	   generate = (bytes || tree) ? TRUE : FALSE;
4056 
4057 	PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
4058 
4059 	DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
4060 
4061 	DISSECTOR_ASSERT_HINT(validate_proto_tree_add_bytes_ftype(hfinfo->type),
4062 		"Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type");
4063 
4064 	/* length has to be -1 or > 0 regardless of encoding */
4065 	/* invalid FT_UINT_BYTES length is caught in get_uint_value() */
4066 	if (length < -1 || length == 0) {
4067 		REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_bytes_item for %s",
4068 		    length, ftype_name(hfinfo->type));
4069 	}
4070 
4071 	if (encoding & ENC_STR_NUM) {
4072 		REPORT_DISSECTOR_BUG("Decoding number strings for byte arrays is not supported");
4073 	}
4074 
4075 	if (generate && (encoding & ENC_STR_HEX)) {
4076 		if (hfinfo->type == FT_UINT_BYTES) {
4077 			/* can't decode FT_UINT_BYTES from strings */
4078 			REPORT_DISSECTOR_BUG("proto_tree_add_bytes_item called for "
4079 			    "FT_UINT_BYTES type, but as ENC_STR_HEX");
4080 		}
4081 
4082 		if (!bytes) {
4083 			/* caller doesn't care about return value, but we need it to
4084 			   call tvb_get_string_bytes() and set the tree later */
4085 			bytes = created_bytes = g_byte_array_new();
4086 		}
4087 
4088 		/* bytes might be NULL after this, but can't add expert error until later */
4089 		bytes = tvb_get_string_bytes(tvb, start, length, encoding, bytes, endoff);
4090 
4091 		/* grab the errno now before it gets overwritten */
4092 		saved_err = errno;
4093 	}
4094 	else if (generate) {
4095 		tvb_ensure_bytes_exist(tvb, start, length);
4096 
4097 		if (!bytes) {
4098 			/* caller doesn't care about return value, but we need it to
4099 			   call tvb_get_string_bytes() and set the tree later */
4100 			bytes = created_bytes = g_byte_array_new();
4101 		}
4102 
4103 		if (hfinfo->type == FT_UINT_BYTES) {
4104 			n = length; /* n is now the "header" length */
4105 			length = get_uint_value(tree, tvb, start, n, encoding);
4106 			/* length is now the value's length; only store the value in the array */
4107 			g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
4108 		}
4109 		else if (length > 0) {
4110 			g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
4111 		}
4112 
4113 		if (endoff)
4114 		    *endoff = start + n + length;
4115 	}
4116 
4117 	if (err) *err = saved_err;
4118 
4119 	CHECK_FOR_NULL_TREE_AND_FREE(tree,
4120 		{
4121 		    if (created_bytes)
4122 			g_byte_array_free(created_bytes, TRUE);
4123 		    created_bytes = NULL;
4124 		    bytes = NULL;
4125 		} );
4126 
4127 	TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfinfo->id, hfinfo,
4128 		{
4129 		    if (created_bytes)
4130 			g_byte_array_free(created_bytes, TRUE);
4131 		    created_bytes = NULL;
4132 		    bytes = NULL;
4133 		} );
4134 
4135 	/* n will be zero except when it's a FT_UINT_BYTES */
4136 	new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
4137 
4138 	if (encoding & ENC_STRING) {
4139 		if (saved_err == ERANGE)
4140 		    expert_add_info(NULL, tree, &ei_number_string_decoding_erange_error);
4141 		else if (!bytes || saved_err != 0)
4142 		    expert_add_info(NULL, tree, &ei_number_string_decoding_failed_error);
4143 
4144 		if (bytes)
4145 		    proto_tree_set_bytes_gbytearray(new_fi, bytes);
4146 		else
4147 		    proto_tree_set_bytes(new_fi, NULL, 0);
4148 
4149 		if (created_bytes)
4150 		    g_byte_array_free(created_bytes, TRUE);
4151 	}
4152 	else {
4153 		/* n will be zero except when it's a FT_UINT_BYTES */
4154 		proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
4155 
4156 		FI_SET_FLAG(new_fi,
4157 			(encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN);
4158 	}
4159 
4160 	return proto_tree_add_node(tree, new_fi);
4161 }
4162 
4163 
4164 proto_item *
proto_tree_add_time_item(proto_tree * tree,int hfindex,tvbuff_t * tvb,const gint start,gint length,const guint encoding,nstime_t * retval,gint * endoff,gint * err)4165 proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4166 			   const gint start, gint length, const guint encoding,
4167 			   nstime_t *retval, gint *endoff, gint *err)
4168 {
4169 	field_info	  *new_fi;
4170 	nstime_t	   time_stamp;
4171 	gint		   saved_err = 0;
4172 	header_field_info *hfinfo;
4173 
4174 	PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
4175 
4176 	DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
4177 
4178 	DISSECTOR_ASSERT_FIELD_TYPE_IS_TIME(hfinfo);
4179 
4180 	/* length has to be -1 or > 0 regardless of encoding */
4181 	if (length < -1 || length == 0) {
4182 		REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_time_item",
4183 		    length);
4184 	}
4185 
4186 	time_stamp.secs  = 0;
4187 	time_stamp.nsecs = 0;
4188 
4189 	if (encoding & ENC_STR_TIME_MASK) {
4190 		tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff);
4191 		/* grab the errno now before it gets overwritten */
4192 		saved_err = errno;
4193 	}
4194 	else {
4195 		const gboolean is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? TRUE : FALSE;
4196 
4197 		tvb_ensure_bytes_exist(tvb, start, length);
4198 		get_time_value(tree, tvb, start, length, encoding, &time_stamp, is_relative);
4199 		if (endoff) *endoff = length;
4200 	}
4201 
4202 	if (err) *err = saved_err;
4203 
4204 	if (retval) {
4205 		retval->secs  = time_stamp.secs;
4206 		retval->nsecs = time_stamp.nsecs;
4207 	}
4208 
4209 	CHECK_FOR_NULL_TREE(tree);
4210 
4211 	TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
4212 
4213 	new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4214 
4215 	proto_tree_set_time(new_fi, &time_stamp);
4216 
4217 	if (encoding & ENC_STRING) {
4218 		if (saved_err == ERANGE)
4219 		    expert_add_info(NULL, tree, &ei_number_string_decoding_erange_error);
4220 		else if (saved_err == EDOM)
4221 		    expert_add_info(NULL, tree, &ei_number_string_decoding_failed_error);
4222 	}
4223 	else {
4224 		FI_SET_FLAG(new_fi,
4225 			(encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN);
4226 	}
4227 
4228 	return proto_tree_add_node(tree, new_fi);
4229 }
4230 
4231 /* Add a FT_NONE to a proto_tree */
4232 proto_item *
proto_tree_add_none_format(proto_tree * tree,const int hfindex,tvbuff_t * tvb,const gint start,gint length,const char * format,...)4233 proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
4234 			   const gint start, gint length, const char *format,
4235 			   ...)
4236 {
4237 	proto_item	  *pi;
4238 	va_list		   ap;
4239 	header_field_info *hfinfo;
4240 
4241 	CHECK_FOR_NULL_TREE(tree);
4242 
4243 	TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4244 
4245 	DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_NONE);
4246 
4247 	pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4248 
4249 	TRY_TO_FAKE_THIS_REPR(pi);
4250 
4251 	va_start(ap, format);
4252 	proto_tree_set_representation(pi, format, ap);
4253 	va_end(ap);
4254 
4255 	/* no value to set for FT_NONE */
4256 	return pi;
4257 }
4258 
4259 /* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
4260  * offset, and returns proto_item* */
4261 proto_item *
ptvcursor_add_no_advance(ptvcursor_t * ptvc,int hf,gint length,const guint encoding)4262 ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, gint length,
4263 			 const guint encoding)
4264 {
4265 	proto_item *item;
4266 
4267 	item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
4268 				   length, encoding);
4269 
4270 	return item;
4271 }
4272 
4273 /* Advance the ptvcursor's offset within its tvbuff without
4274  * adding anything to the proto_tree. */
4275 void
ptvcursor_advance(ptvcursor_t * ptvc,gint length)4276 ptvcursor_advance(ptvcursor_t* ptvc, gint length)
4277 {
4278 	ptvc->offset += length;
4279 }
4280 
4281 
4282 static void
proto_tree_set_protocol_tvb(field_info * fi,tvbuff_t * tvb,const char * field_data)4283 proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data)
4284 {
4285 	fvalue_set_protocol(&fi->value, tvb, field_data);
4286 }
4287 
4288 /* Add a FT_PROTOCOL to a proto_tree */
4289 proto_item *
proto_tree_add_protocol_format(proto_tree * tree,int hfindex,tvbuff_t * tvb,gint start,gint length,const char * format,...)4290 proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4291 			       gint start, gint length, const char *format, ...)
4292 {
4293 	proto_item	  *pi;
4294 	tvbuff_t	  *protocol_tvb;
4295 	va_list		   ap;
4296 	header_field_info *hfinfo;
4297 	gchar* protocol_rep;
4298 
4299 	CHECK_FOR_NULL_TREE(tree);
4300 
4301 	TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4302 
4303 	DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_PROTOCOL);
4304 
4305 	/*
4306 	 * This can throw an exception, so do it before we allocate anything.
4307 	 */
4308 	protocol_tvb = (start == 0 ? tvb : tvb_new_subset_length(tvb, start, length));
4309 
4310 	pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4311 
4312 	va_start(ap, format);
4313 	protocol_rep = g_strdup_vprintf(format, ap);
4314 	proto_tree_set_protocol_tvb(PNODE_FINFO(pi), protocol_tvb, protocol_rep);
4315 	g_free(protocol_rep);
4316 	va_end(ap);
4317 
4318 	TRY_TO_FAKE_THIS_REPR(pi);
4319 
4320 	va_start(ap, format);
4321 	proto_tree_set_representation(pi, format, ap);
4322 	va_end(ap);
4323 
4324 	return pi;
4325 }
4326 
4327 /* Add a FT_BYTES to a proto_tree */
4328 proto_item *
proto_tree_add_bytes(proto_tree * tree,int hfindex,tvbuff_t * tvb,gint start,gint length,const guint8 * start_ptr)4329 proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4330 		     gint length, const guint8 *start_ptr)
4331 {
4332 	proto_item	  *pi;
4333 	header_field_info *hfinfo;
4334 	gint		  item_length;
4335 
4336 	PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
4337 	get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA);
4338 	test_length(hfinfo, tvb, start, item_length, ENC_NA);
4339 
4340 	CHECK_FOR_NULL_TREE(tree);
4341 
4342 	TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4343 
4344 	DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BYTES);
4345 
4346 	pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4347 	proto_tree_set_bytes(PNODE_FINFO(pi), start_ptr, length);
4348 
4349 	return pi;
4350 }
4351 
4352 /* Add a FT_BYTES to a proto_tree */
4353 proto_item *
proto_tree_add_bytes_with_length(proto_tree * tree,int hfindex,tvbuff_t * tvb,gint start,gint tvbuff_length,const guint8 * start_ptr,gint ptr_length)4354 proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4355              gint tvbuff_length, const guint8 *start_ptr, gint ptr_length)
4356 {
4357 	proto_item    *pi;
4358 	header_field_info *hfinfo;
4359 	gint          item_length;
4360 
4361 	PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
4362 	get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length, ENC_NA);
4363 	test_length(hfinfo, tvb, start, item_length, ENC_NA);
4364 
4365 	CHECK_FOR_NULL_TREE(tree);
4366 
4367 	TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4368 
4369 	DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BYTES);
4370 
4371 	pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
4372 	proto_tree_set_bytes(PNODE_FINFO(pi), start_ptr, ptr_length);
4373 
4374 	return pi;
4375 }
4376 
4377 proto_item *
proto_tree_add_bytes_format_value(proto_tree * tree,int hfindex,tvbuff_t * tvb,gint start,gint length,const guint8 * start_ptr,const char * format,...)4378 proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4379 				  gint start, gint length,
4380 				  const guint8 *start_ptr,
4381 				  const char *format, ...)
4382 {
4383 	proto_item	  *pi;
4384 	va_list		   ap;
4385 
4386 	if (start_ptr == NULL)
4387 		start_ptr = tvb_get_ptr(tvb, start, length);
4388 
4389 	pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4390 
4391 	TRY_TO_FAKE_THIS_REPR_NESTED(pi);
4392 
4393 	va_start(ap, format);
4394 	proto_tree_set_representation_value(pi, format, ap);
4395 	va_end(ap);
4396 
4397 	return pi;
4398 }
4399 
4400 proto_item *
proto_tree_add_bytes_format(proto_tree * tree,int hfindex,tvbuff_t * tvb,gint start,gint length,const guint8 * start_ptr,const char * format,...)4401 proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4402 			    gint start, gint length, const guint8 *start_ptr,
4403 			    const char *format, ...)
4404 {
4405 	proto_item	  *pi;
4406 	va_list		   ap;
4407 
4408 	if (start_ptr == NULL)
4409 		start_ptr = tvb_get_ptr(tvb, start, length);
4410 
4411 	pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4412 
4413 	TRY_TO_FAKE_THIS_REPR_NESTED(pi);
4414 
4415 	va_start(ap, format);
4416 	proto_tree_set_representation(pi, format, ap);
4417 	va_end(ap);
4418 
4419 	return pi;
4420 }
4421 
4422 static void
proto_tree_set_bytes(field_info * fi,const guint8 * start_ptr,gint length)4423 proto_tree_set_bytes(field_info *fi, const guint8* start_ptr, gint length)
4424 {
4425 	GByteArray *bytes;
4426 
4427 	DISSECTOR_ASSERT(start_ptr != NULL || length == 0);
4428 
4429 	bytes = g_byte_array_new();
4430 	if (length > 0) {
4431 		g_byte_array_append(bytes, start_ptr, length);
4432 	}
4433 	fvalue_set_byte_array(&fi->value, bytes);
4434 }
4435 
4436 
4437 static void
proto_tree_set_bytes_tvb(field_info * fi,tvbuff_t * tvb,gint offset,gint length)4438 proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, gint offset, gint length)
4439 {
4440 	proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
4441 }
4442 
4443 static void
proto_tree_set_bytes_gbytearray(field_info * fi,const GByteArray * value)4444 proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
4445 {
4446 	GByteArray *bytes;
4447 
4448 	DISSECTOR_ASSERT(value != NULL);
4449 
4450 	bytes = byte_array_dup(value);
4451 
4452 	fvalue_set_byte_array(&fi->value, bytes);
4453 }
4454 
4455 /* Add a FT_*TIME to a proto_tree */
4456 proto_item *
proto_tree_add_time(proto_tree * tree,int hfindex,tvbuff_t * tvb,gint start,gint length,const nstime_t * value_ptr)4457 proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4458 		    gint length, const nstime_t *value_ptr)
4459 {
4460 	proto_item	  *pi;
4461 	header_field_info *hfinfo;
4462 
4463 	CHECK_FOR_NULL_TREE(tree);
4464 
4465 	TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4466 
4467 	DISSECTOR_ASSERT_FIELD_TYPE_IS_TIME(hfinfo);
4468 
4469 	pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4470 	proto_tree_set_time(PNODE_FINFO(pi), value_ptr);
4471 
4472 	return pi;
4473 }
4474 
4475 proto_item *
proto_tree_add_time_format_value(proto_tree * tree,int hfindex,tvbuff_t * tvb,gint start,gint length,nstime_t * value_ptr,const char * format,...)4476 proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4477 				 gint start, gint length, nstime_t *value_ptr,
4478 				 const char *format, ...)
4479 {
4480 	proto_item	  *pi;
4481 	va_list		   ap;
4482 
4483 	pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
4484 	if (pi != tree) {
4485 		va_start(ap, format);
4486 		proto_tree_set_representation_value(pi, format, ap);
4487 		va_end(ap);
4488 	}
4489 
4490 	return pi;
4491 }
4492 
4493 proto_item *
proto_tree_add_time_format(proto_tree * tree,int hfindex,tvbuff_t * tvb,gint start,gint length,nstime_t * value_ptr,const char * format,...)4494 proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4495 			   gint start, gint length, nstime_t *value_ptr,
4496 			   const char *format, ...)
4497 {
4498 	proto_item	  *pi;
4499 	va_list		   ap;
4500 
4501 	pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
4502 	if (pi != tree) {
4503 		TRY_TO_FAKE_THIS_REPR(pi);
4504 
4505 		va_start(ap, format);
4506 		proto_tree_set_representation(pi, format, ap);
4507 		va_end(ap);
4508 	}
4509 
4510 	return pi;
4511 }
4512 
4513 /* Set the FT_*TIME value */
4514 static void
proto_tree_set_time(field_info * fi,const nstime_t * value_ptr)4515 proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
4516 {
4517 	DISSECTOR_ASSERT(value_ptr != NULL);
4518 
4519 	fvalue_set_time(&fi->value, value_ptr);
4520 }
4521 
4522 /* Add a FT_IPXNET to a proto_tree */
4523 proto_item *
proto_tree_add_ipxnet(proto_tree * tree,int hfindex,tvbuff_t * tvb,gint start,gint length,guint32 value)4524 proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4525 		      gint length, guint32 value)
4526 {
4527 	proto_item	  *pi;
4528 	header_field_info *hfinfo;
4529 
4530 	CHECK_FOR_NULL_TREE(tree);
4531 
4532 	TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4533 
4534 	DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_IPXNET);
4535 
4536 	pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4537 	proto_tree_set_ipxnet(PNODE_FINFO(pi), value);
4538 
4539 	return pi;
4540 }
4541 
4542 proto_item *
proto_tree_add_ipxnet_format_value(proto_tree * tree,int hfindex,tvbuff_t * tvb,gint start,gint length,guint32 value,const char * format,...)4543 proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4544 				   gint start, gint length, guint32 value,
4545 				   const char *format, ...)
4546 {
4547 	proto_item	  *pi;
4548 	va_list		   ap;
4549 
4550 	pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
4551 	if (pi != tree) {
4552 		va_start(ap, format);
4553 		proto_tree_set_representation_value(pi, format, ap);
4554 		va_end(ap);
4555 	}
4556 
4557 	return pi;
4558 }
4559 
4560 proto_item *
proto_tree_add_ipxnet_format(proto_tree * tree,int hfindex,tvbuff_t * tvb,gint start,gint length,guint32 value,const char * format,...)4561 proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4562 			     gint start, gint length, guint32 value,
4563 			     const char *format, ...)
4564 {
4565 	proto_item	  *pi;
4566 	va_list		   ap;
4567 
4568 	pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
4569 	if (pi != tree) {
4570 		TRY_TO_FAKE_THIS_REPR(pi);
4571 
4572 		va_start(ap, format);
4573 		proto_tree_set_representation(pi, format, ap);
4574 		va_end(ap);
4575 	}
4576 
4577 	return pi;
4578 }
4579 
4580 /* Set the FT_IPXNET value */
4581 static void
proto_tree_set_ipxnet(field_info * fi,guint32 value)4582 proto_tree_set_ipxnet(field_info *fi, guint32 value)
4583 {
4584 	fvalue_set_uinteger(&fi->value, value);
4585 }
4586 
4587 /* Add a FT_IPv4 to a proto_tree */
4588 proto_item *
proto_tree_add_ipv4(proto_tree * tree,int hfindex,tvbuff_t * tvb,gint start,gint length,ws_in4_addr value)4589 proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4590 		    gint length, ws_in4_addr value)
4591 {
4592 	proto_item	  *pi;
4593 	header_field_info *hfinfo;
4594 
4595 	CHECK_FOR_NULL_TREE(tree);
4596 
4597 	TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4598 
4599 	DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_IPv4);
4600 
4601 	pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4602 	proto_tree_set_ipv4(PNODE_FINFO(pi), value);
4603 
4604 	return pi;
4605 }
4606 
4607 proto_item *
proto_tree_add_ipv4_format_value(proto_tree * tree,int hfindex,tvbuff_t * tvb,gint start,gint length,ws_in4_addr value,const char * format,...)4608 proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4609 				 gint start, gint length, ws_in4_addr value,
4610 				 const char *format, ...)
4611 {
4612 	proto_item	  *pi;
4613 	va_list		   ap;
4614 
4615 	pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
4616 	if (pi != tree) {
4617 		va_start(ap, format);
4618 		proto_tree_set_representation_value(pi, format, ap);
4619 		va_end(ap);
4620 	}
4621 
4622 	return pi;
4623 }
4624 
4625 proto_item *
proto_tree_add_ipv4_format(proto_tree * tree,int hfindex,tvbuff_t * tvb,gint start,gint length,ws_in4_addr value,const char * format,...)4626 proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4627 			   gint start, gint length, ws_in4_addr value,
4628 			   const char *format, ...)
4629 {
4630 	proto_item	  *pi;
4631 	va_list		   ap;
4632 
4633 	pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
4634 	if (pi != tree) {
4635 		TRY_TO_FAKE_THIS_REPR(pi);
4636 
4637 		va_start(ap, format);
4638 		proto_tree_set_representation(pi, format, ap);
4639 		va_end(ap);
4640 	}
4641 
4642 	return pi;
4643 }
4644 
4645 /* Set the FT_IPv4 value */
4646 static void
proto_tree_set_ipv4(field_info * fi,ws_in4_addr value)4647 proto_tree_set_ipv4(field_info *fi, ws_in4_addr value)
4648 {
4649 	fvalue_set_uinteger(&fi->value, value);
4650 }
4651 
4652 /* Add a FT_IPv6 to a proto_tree */
4653 proto_item *
proto_tree_add_ipv6(proto_tree * tree,int hfindex,tvbuff_t * tvb,gint start,gint length,const ws_in6_addr * value_ptr)4654 proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4655 		    gint length, const ws_in6_addr *value_ptr)
4656 {
4657 	proto_item	  *pi;
4658 	header_field_info *hfinfo;
4659 
4660 	CHECK_FOR_NULL_TREE(tree);
4661 
4662 	TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4663 
4664 	DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_IPv6);
4665 
4666 	pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4667 	proto_tree_set_ipv6(PNODE_FINFO(pi), value_ptr->bytes);
4668 
4669 	return pi;
4670 }
4671 
4672 proto_item *
proto_tree_add_ipv6_format_value(proto_tree * tree,int hfindex,tvbuff_t * tvb,gint start,gint length,const ws_in6_addr * value_ptr,const char * format,...)4673 proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4674 				 gint start, gint length,
4675 				 const ws_in6_addr *value_ptr,
4676 				 const char *format, ...)
4677 {
4678 	proto_item	  *pi;
4679 	va_list		   ap;
4680 
4681 	pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
4682 	if (pi != tree) {
4683 		va_start(ap, format);
4684 		proto_tree_set_representation_value(pi, format, ap);
4685 		va_end(ap);
4686 	}
4687 
4688 	return pi;
4689 }
4690 
4691 proto_item *
proto_tree_add_ipv6_format(proto_tree * tree,int hfindex,tvbuff_t * tvb,gint start,gint length,const ws_in6_addr * value_ptr,const char * format,...)4692 proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4693 			   gint start, gint length,
4694 			   const ws_in6_addr *value_ptr,
4695 			   const char *format, ...)
4696 {
4697 	proto_item	  *pi;
4698 	va_list		   ap;
4699 
4700 	pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
4701 	if (pi != tree) {
4702 		TRY_TO_FAKE_THIS_REPR(pi);
4703 
4704 		va_start(ap, format);
4705 		proto_tree_set_representation(pi, format, ap);
4706 		va_end(ap);
4707 	}
4708 
4709 	return pi;
4710 }
4711 
4712 /* Set the FT_IPv6 value */
4713 static void
proto_tree_set_ipv6(field_info * fi,const guint8 * value_ptr)4714 proto_tree_set_ipv6(field_info *fi, const guint8* value_ptr)
4715 {
4716 	DISSECTOR_ASSERT(value_ptr != NULL);
4717 	fvalue_set_bytes(&fi->value, value_ptr);
4718 }
4719 
4720 static void
proto_tree_set_ipv6_tvb(field_info * fi,tvbuff_t * tvb,gint start,gint length)4721 proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
4722 {
4723 	proto_tree_set_ipv6(fi, tvb_get_ptr(tvb, start, length));
4724 }
4725 
4726 /* Set the FT_FCWWN value */
4727 static void
proto_tree_set_fcwwn(field_info * fi,const guint8 * value_ptr)4728 proto_tree_set_fcwwn(field_info *fi, const guint8* value_ptr)
4729 {
4730 	DISSECTOR_ASSERT(value_ptr != NULL);
4731 	fvalue_set_bytes(&fi->value, value_ptr);
4732 }
4733 
4734 static void
proto_tree_set_fcwwn_tvb(field_info * fi,tvbuff_t * tvb,gint start,gint length)4735 proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
4736 {
4737 	proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
4738 }
4739 
4740 /* Add a FT_GUID to a proto_tree */
4741 proto_item *
proto_tree_add_guid(proto_tree * tree,int hfindex,tvbuff_t * tvb,gint start,gint length,const e_guid_t * value_ptr)4742 proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4743 		    gint length, const e_guid_t *value_ptr)
4744 {
4745 	proto_item	  *pi;
4746 	header_field_info *hfinfo;
4747 
4748 	CHECK_FOR_NULL_TREE(tree);
4749 
4750 	TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4751 
4752 	DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_GUID);
4753 
4754 	pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4755 	proto_tree_set_guid(PNODE_FINFO(pi), value_ptr);
4756 
4757 	return pi;
4758 }
4759 
4760 proto_item *
proto_tree_add_guid_format_value(proto_tree * tree,int hfindex,tvbuff_t * tvb,gint start,gint length,const e_guid_t * value_ptr,const char * format,...)4761 proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4762 				 gint start, gint length,
4763 				 const e_guid_t *value_ptr,
4764 				 const char *format, ...)
4765 {
4766 	proto_item	  *pi;
4767 	va_list		   ap;
4768 
4769 	pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
4770 	if (pi != tree) {
4771 		va_start(ap, format);
4772 		proto_tree_set_representation_value(pi, format, ap);
4773 		va_end(ap);
4774 	}
4775 
4776 	return pi;
4777 }
4778 
4779 proto_item *
proto_tree_add_guid_format(proto_tree * tree,int hfindex,tvbuff_t * tvb,gint start,gint length,const e_guid_t * value_ptr,const char * format,...)4780 proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4781 			   gint start, gint length, const e_guid_t *value_ptr,
4782 			   const char *format, ...)
4783 {
4784 	proto_item	  *pi;
4785 	va_list		   ap;
4786 
4787 	pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
4788 	if (pi != tree) {
4789 		TRY_TO_FAKE_THIS_REPR(pi);
4790 
4791 		va_start(ap, format);
4792 		proto_tree_set_representation(pi, format, ap);
4793 		va_end(ap);
4794 	}
4795 
4796 	return pi;
4797 }
4798 
4799 /* Set the FT_GUID value */
4800 static void
proto_tree_set_guid(field_info * fi,const e_guid_t * value_ptr)4801 proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
4802 {
4803 	DISSECTOR_ASSERT(value_ptr != NULL);
4804 	fvalue_set_guid(&fi->value, value_ptr);
4805 }
4806 
4807 static void
proto_tree_set_guid_tvb(field_info * fi,tvbuff_t * tvb,gint start,const guint encoding)4808 proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, gint start,
4809 			const guint encoding)
4810 {
4811 	e_guid_t guid;
4812 
4813 	tvb_get_guid(tvb, start, &guid, encoding);
4814 	proto_tree_set_guid(fi, &guid);
4815 }
4816 
4817 /* Add a FT_OID to a proto_tree */
4818 proto_item *
proto_tree_add_oid(proto_tree * tree,int hfindex,tvbuff_t * tvb,gint start,gint length,const guint8 * value_ptr)4819 proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4820 		   gint length, const guint8* value_ptr)
4821 {
4822 	proto_item	  *pi;
4823 	header_field_info *hfinfo;
4824 
4825 	CHECK_FOR_NULL_TREE(tree);
4826 
4827 	TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4828 
4829 	DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_OID);
4830 
4831 	pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4832 	proto_tree_set_oid(PNODE_FINFO(pi), value_ptr, length);
4833 
4834 	return pi;
4835 }
4836 
4837 proto_item *
proto_tree_add_oid_format_value(proto_tree * tree,int hfindex,tvbuff_t * tvb,gint start,gint length,const guint8 * value_ptr,const char * format,...)4838 proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4839 				gint start, gint length,
4840 				const guint8* value_ptr,
4841 				const char *format, ...)
4842 {
4843 	proto_item	  *pi;
4844 	va_list		   ap;
4845 
4846 	pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
4847 	if (pi != tree) {
4848 		va_start(ap, format);
4849 		proto_tree_set_representation_value(pi, format, ap);
4850 		va_end(ap);
4851 	}
4852 
4853 	return pi;
4854 }
4855 
4856 proto_item *
proto_tree_add_oid_format(proto_tree * tree,int hfindex,tvbuff_t * tvb,gint start,gint length,const guint8 * value_ptr,const char * format,...)4857 proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4858 			  gint start, gint length, const guint8* value_ptr,
4859 			  const char *format, ...)
4860 {
4861 	proto_item	  *pi;
4862 	va_list		   ap;
4863 
4864 	pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
4865 	if (pi != tree) {
4866 		TRY_TO_FAKE_THIS_REPR(pi);
4867 
4868 		va_start(ap, format);
4869 		proto_tree_set_representation(pi, format, ap);
4870 		va_end(ap);
4871 	}
4872 
4873 	return pi;
4874 }
4875 
4876 /* Set the FT_OID value */
4877 static void
proto_tree_set_oid(field_info * fi,const guint8 * value_ptr,gint length)4878 proto_tree_set_oid(field_info *fi, const guint8* value_ptr, gint length)
4879 {
4880 	GByteArray *bytes;
4881 
4882 	DISSECTOR_ASSERT(value_ptr != NULL || length == 0);
4883 
4884 	bytes = g_byte_array_new();
4885 	if (length > 0) {
4886 		g_byte_array_append(bytes, value_ptr, length);
4887 	}
4888 	fvalue_set_byte_array(&fi->value, bytes);
4889 }
4890 
4891 static void
proto_tree_set_oid_tvb(field_info * fi,tvbuff_t * tvb,gint start,gint length)4892 proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
4893 {
4894 	proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
4895 }
4896 
4897 /* Set the FT_SYSTEM_ID value */
4898 static void
proto_tree_set_system_id(field_info * fi,const guint8 * value_ptr,gint length)4899 proto_tree_set_system_id(field_info *fi, const guint8* value_ptr, gint length)
4900 {
4901 	GByteArray *bytes;
4902 
4903 	DISSECTOR_ASSERT(value_ptr != NULL || length == 0);
4904 
4905 	bytes = g_byte_array_new();
4906 	if (length > 0) {
4907 		g_byte_array_append(bytes, value_ptr, length);
4908 	}
4909 	fvalue_set_byte_array(&fi->value, bytes);
4910 }
4911 
4912 static void
proto_tree_set_system_id_tvb(field_info * fi,tvbuff_t * tvb,gint start,gint length)4913 proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
4914 {
4915 	proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
4916 }
4917 
4918 /* Add a FT_STRING, FT_STRINGZ, FT_STRINGZPAD, or FT_STRINGZTRUNC to a
4919  * proto_tree. Creates own copy of string, and frees it when the proto_tree
4920  * is destroyed. */
4921 proto_item *
proto_tree_add_string(proto_tree * tree,int hfindex,tvbuff_t * tvb,gint start,gint length,const char * value)4922 proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4923 		      gint length, const char* value)
4924 {
4925 	proto_item	  *pi;
4926 	header_field_info *hfinfo;
4927 	gint		  item_length;
4928 
4929 	PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
4930 	get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA);
4931 	/*
4932 	 * Special case - if the length is 0, skip the test, so that
4933 	 * we can have an empty string right after the end of the
4934 	 * packet.  (This handles URL-encoded forms where the last field
4935 	 * has no value so the form ends right after the =.)
4936 	 */
4937 	if (item_length != 0)
4938 		test_length(hfinfo, tvb, start, item_length, ENC_NA);
4939 
4940 	CHECK_FOR_NULL_TREE(tree);
4941 
4942 	TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4943 
4944 	DISSECTOR_ASSERT_FIELD_TYPE_IS_STRING(hfinfo);
4945 
4946 	pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4947 	DISSECTOR_ASSERT(length >= 0);
4948 	proto_tree_set_string(PNODE_FINFO(pi), value);
4949 
4950 	return pi;
4951 }
4952 
4953 proto_item *
proto_tree_add_string_format_value(proto_tree * tree,int hfindex,tvbuff_t * tvb,gint start,gint length,const char * value,const char * format,...)4954 proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4955 				   gint start, gint length, const char* value,
4956 				   const char *format,
4957 				   ...)
4958 {
4959 	proto_item	  *pi;
4960 	va_list		   ap;
4961 
4962 	pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
4963 	if (pi != tree) {
4964 		va_start(ap, format);
4965 		proto_tree_set_representation_value(pi, format, ap);
4966 		va_end(ap);
4967 	}
4968 
4969 	return pi;
4970 }
4971 
4972 proto_item *
proto_tree_add_string_format(proto_tree * tree,int hfindex,tvbuff_t * tvb,gint start,gint length,const char * value,const char * format,...)4973 proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4974 			     gint start, gint length, const char* value,
4975 			     const char *format, ...)
4976 {
4977 	proto_item	  *pi;
4978 	va_list		   ap;
4979 
4980 	pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
4981 	if (pi != tree) {
4982 		TRY_TO_FAKE_THIS_REPR(pi);
4983 
4984 		va_start(ap, format);
4985 		proto_tree_set_representation(pi, format, ap);
4986 		va_end(ap);
4987 	}
4988 
4989 	return pi;
4990 }
4991 
4992 /* Set the FT_STRING value */
4993 static void
proto_tree_set_string(field_info * fi,const char * value)4994 proto_tree_set_string(field_info *fi, const char* value)
4995 {
4996 	if (value) {
4997 		fvalue_set_string(&fi->value, value);
4998 	} else {
4999 		/*
5000 		 * XXX - why is a null value for a string field
5001 		 * considered valid?
5002 		 */
5003 		fvalue_set_string(&fi->value, "[ Null ]");
5004 	}
5005 }
5006 
5007 /* Set the FT_AX25 value */
5008 static void
proto_tree_set_ax25(field_info * fi,const guint8 * value)5009 proto_tree_set_ax25(field_info *fi, const guint8* value)
5010 {
5011 	fvalue_set_bytes(&fi->value, value);
5012 }
5013 
5014 static void
proto_tree_set_ax25_tvb(field_info * fi,tvbuff_t * tvb,gint start)5015 proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, gint start)
5016 {
5017 	proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
5018 }
5019 
5020 /* Set the FT_VINES value */
5021 static void
proto_tree_set_vines(field_info * fi,const guint8 * value)5022 proto_tree_set_vines(field_info *fi, const guint8* value)
5023 {
5024 	fvalue_set_bytes(&fi->value, value);
5025 }
5026 
5027 static void
proto_tree_set_vines_tvb(field_info * fi,tvbuff_t * tvb,gint start)5028 proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, gint start)
5029 {
5030 	proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN));
5031 }
5032 
5033 /* Add a FT_ETHER to a proto_tree */
5034 proto_item *
proto_tree_add_ether(proto_tree * tree,int hfindex,tvbuff_t * tvb,gint start,gint length,const guint8 * value)5035 proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
5036 		     gint length, const guint8* value)
5037 {
5038 	proto_item	  *pi;
5039 	header_field_info *hfinfo;
5040 
5041 	CHECK_FOR_NULL_TREE(tree);
5042 
5043 	TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
5044 
5045 	DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_ETHER);
5046 
5047 	pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5048 	proto_tree_set_ether(PNODE_FINFO(pi), value);
5049 
5050 	return pi;
5051 }
5052 
5053 proto_item *
proto_tree_add_ether_format_value(proto_tree * tree,int hfindex,tvbuff_t * tvb,gint start,gint length,const guint8 * value,const char * format,...)5054 proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5055 				  gint start, gint length, const guint8* value,
5056 				  const char *format, ...)
5057 {
5058 	proto_item	  *pi;
5059 	va_list		   ap;
5060 
5061 	pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5062 	if (pi != tree) {
5063 		va_start(ap, format);
5064 		proto_tree_set_representation_value(pi, format, ap);
5065 		va_end(ap);
5066 	}
5067 
5068 	return pi;
5069 }
5070 
5071 proto_item *
proto_tree_add_ether_format(proto_tree * tree,int hfindex,tvbuff_t * tvb,gint start,gint length,const guint8 * value,const char * format,...)5072 proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5073 			    gint start, gint length, const guint8* value,
5074 			    const char *format, ...)
5075 {
5076 	proto_item	  *pi;
5077 	va_list		   ap;
5078 
5079 	pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5080 	if (pi != tree) {
5081 		TRY_TO_FAKE_THIS_REPR(pi);
5082 
5083 		va_start(ap, format);
5084 		proto_tree_set_representation(pi, format, ap);
5085 		va_end(ap);
5086 	}
5087 
5088 	return pi;
5089 }
5090 
5091 /* Set the FT_ETHER value */
5092 static void
proto_tree_set_ether(field_info * fi,const guint8 * value)5093 proto_tree_set_ether(field_info *fi, const guint8* value)
5094 {
5095 	fvalue_set_bytes(&fi->value, value);
5096 }
5097 
5098 static void
proto_tree_set_ether_tvb(field_info * fi,tvbuff_t * tvb,gint start)5099 proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, gint start)
5100 {
5101 	proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN));
5102 }
5103 
5104 /* Add a FT_BOOLEAN to a proto_tree */
5105 proto_item *
proto_tree_add_boolean(proto_tree * tree,int hfindex,tvbuff_t * tvb,gint start,gint length,guint32 value)5106 proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
5107 		       gint length, guint32 value)
5108 {
5109 	proto_item	  *pi;
5110 	header_field_info *hfinfo;
5111 
5112 	CHECK_FOR_NULL_TREE(tree);
5113 
5114 	TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
5115 
5116 	DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BOOLEAN);
5117 
5118 	pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5119 	proto_tree_set_boolean(PNODE_FINFO(pi), value);
5120 
5121 	return pi;
5122 }
5123 
5124 proto_item *
proto_tree_add_boolean_format_value(proto_tree * tree,int hfindex,tvbuff_t * tvb,gint start,gint length,guint32 value,const char * format,...)5125 proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
5126 				    tvbuff_t *tvb, gint start, gint length,
5127 				    guint32 value, const char *format, ...)
5128 {
5129 	proto_item	  *pi;
5130 	va_list		   ap;
5131 
5132 	pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5133 	if (pi != tree) {
5134 		va_start(ap, format);
5135 		proto_tree_set_representation_value(pi, format, ap);
5136 		va_end(ap);
5137 	}
5138 
5139 	return pi;
5140 }
5141 
5142 proto_item *
proto_tree_add_boolean_format(proto_tree * tree,int hfindex,tvbuff_t * tvb,gint start,gint length,guint32 value,const char * format,...)5143 proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5144 			      gint start, gint length, guint32 value,
5145 			      const char *format, ...)
5146 {
5147 	proto_item	  *pi;
5148 	va_list		   ap;
5149 
5150 	pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5151 	if (pi != tree) {
5152 		TRY_TO_FAKE_THIS_REPR(pi);
5153 
5154 		va_start(ap, format);
5155 		proto_tree_set_representation(pi, format, ap);
5156 		va_end(ap);
5157 	}
5158 
5159 	return pi;
5160 }
5161 
5162 static proto_item *
proto_tree_add_boolean64(proto_tree * tree,int hfindex,tvbuff_t * tvb,gint start,gint length,guint64 value)5163 proto_tree_add_boolean64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
5164 		         gint length, guint64 value)
5165 {
5166 	proto_item	  *pi;
5167 	header_field_info *hfinfo;
5168 
5169 	CHECK_FOR_NULL_TREE(tree);
5170 
5171 	TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
5172 
5173 	DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BOOLEAN);
5174 
5175 	pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5176 	proto_tree_set_boolean(PNODE_FINFO(pi), value);
5177 
5178 	return pi;
5179 }
5180 
5181 /* Set the FT_BOOLEAN value */
5182 static void
proto_tree_set_boolean(field_info * fi,guint64 value)5183 proto_tree_set_boolean(field_info *fi, guint64 value)
5184 {
5185 	proto_tree_set_uint64(fi, value);
5186 }
5187 
5188 /* Generate, into "buf", a string showing the bits of a bitfield.
5189    Return a pointer to the character after that string. */
5190 static char *
other_decode_bitfield_value(char * buf,const guint64 val,const guint64 mask,const int width)5191 other_decode_bitfield_value(char *buf, const guint64 val, const guint64 mask, const int width)
5192 {
5193 	int i;
5194 	guint64 bit;
5195 	char *p;
5196 
5197 	i = 0;
5198 	p = buf;
5199 
5200 	/* This is a devel error. It is safer to stop here. */
5201 	DISSECTOR_ASSERT(width >= 1);
5202 
5203 	bit = G_GUINT64_CONSTANT(1) << (width - 1);
5204 	for (;;) {
5205 		if (mask & bit) {
5206 			/* This bit is part of the field.  Show its value. */
5207 			if (val & bit)
5208 				*p++ = '1';
5209 			else
5210 				*p++ = '0';
5211 		} else {
5212 			/* This bit is not part of the field. */
5213 			*p++ = '.';
5214 		}
5215 		bit >>= 1;
5216 		i++;
5217 		if (i >= width)
5218 			break;
5219 		if (i % 4 == 0)
5220 			*p++ = ' ';
5221 	}
5222 	*p = '\0';
5223 	return p;
5224 }
5225 
5226 static char *
decode_bitfield_value(char * buf,const guint64 val,const guint64 mask,const int width)5227 decode_bitfield_value(char *buf, const guint64 val, const guint64 mask, const int width)
5228 {
5229 	char *p;
5230 
5231 	p = other_decode_bitfield_value(buf, val, mask, width);
5232 	p = g_stpcpy(p, " = ");
5233 
5234 	return p;
5235 }
5236 
5237 static char *
other_decode_bitfield_varint_value(char * buf,guint64 val,guint64 mask,const int width)5238 other_decode_bitfield_varint_value(char *buf, guint64 val, guint64 mask, const int width)
5239 {
5240 	int i = 0;
5241 	guint64 bit;
5242 	char *p;
5243 
5244 	p = buf;
5245 	bit = G_GUINT64_CONSTANT(1) << (width - 1);
5246 	for (;;) {
5247 		if (((8-(i % 8)) != 8) && /* MSB is never used for value. */
5248 			(mask & bit)) {
5249 			/* This bit is part of the field.  Show its value. */
5250 			if (val & bit)
5251 				*p++ = '1';
5252 			else
5253 				*p++ = '0';
5254 		} else {
5255 			/* This bit is not part of the field. */
5256 			*p++ = '.';
5257 		}
5258 		bit >>= 1;
5259 		i++;
5260 		if (i >= width)
5261 			break;
5262 		if (i % 4 == 0)
5263 			*p++ = ' ';
5264 	}
5265 
5266 	*p = '\0';
5267 	return p;
5268 }
5269 
5270 static char *
decode_bitfield_varint_value(char * buf,const guint64 val,const guint64 mask,const int width)5271 decode_bitfield_varint_value(char *buf, const guint64 val, const guint64 mask, const int width)
5272 {
5273 	char *p;
5274 
5275 	p = other_decode_bitfield_varint_value(buf, val, mask, width);
5276 	p = g_stpcpy(p, " = ");
5277 
5278 	return p;
5279 }
5280 
5281 /* Add a FT_FLOAT to a proto_tree */
5282 proto_item *
proto_tree_add_float(proto_tree * tree,int hfindex,tvbuff_t * tvb,gint start,gint length,float value)5283 proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
5284 		     gint length, float value)
5285 {
5286 	proto_item	  *pi;
5287 	header_field_info *hfinfo;
5288 
5289 	CHECK_FOR_NULL_TREE(tree);
5290 
5291 	TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
5292 
5293 	DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_FLOAT);
5294 
5295 	pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5296 	proto_tree_set_float(PNODE_FINFO(pi), value);
5297 
5298 	return pi;
5299 }
5300 
5301 proto_item *
proto_tree_add_float_format_value(proto_tree * tree,int hfindex,tvbuff_t * tvb,gint start,gint length,float value,const char * format,...)5302 proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5303 				  gint start, gint length, float value,
5304 				  const char *format, ...)
5305 {
5306 	proto_item	  *pi;
5307 	va_list		   ap;
5308 
5309 	pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5310 	if (pi != tree) {
5311 		va_start(ap, format);
5312 		proto_tree_set_representation_value(pi, format, ap);
5313 		va_end(ap);
5314 	}
5315 
5316 	return pi;
5317 }
5318 
5319 proto_item *
proto_tree_add_float_format(proto_tree * tree,int hfindex,tvbuff_t * tvb,gint start,gint length,float value,const char * format,...)5320 proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5321 			    gint start, gint length, float value,
5322 			    const char *format, ...)
5323 {
5324 	proto_item	  *pi;
5325 	va_list		   ap;
5326 
5327 	pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5328 	if (pi != tree) {
5329 		TRY_TO_FAKE_THIS_REPR(pi);
5330 
5331 		va_start(ap, format);
5332 		proto_tree_set_representation(pi, format, ap);
5333 		va_end(ap);
5334 	}
5335 
5336 	return pi;
5337 }
5338 
5339 /* Set the FT_FLOAT value */
5340 static void
proto_tree_set_float(field_info * fi,float value)5341 proto_tree_set_float(field_info *fi, float value)
5342 {
5343 	fvalue_set_floating(&fi->value, value);
5344 }
5345 
5346 /* Add a FT_DOUBLE to a proto_tree */
5347 proto_item *
proto_tree_add_double(proto_tree * tree,int hfindex,tvbuff_t * tvb,gint start,gint length,double value)5348 proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
5349 		      gint length, double value)
5350 {
5351 	proto_item	  *pi;
5352 	header_field_info *hfinfo;
5353 
5354 	CHECK_FOR_NULL_TREE(tree);
5355 
5356 	TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
5357 
5358 	DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_DOUBLE);
5359 
5360 	pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5361 	proto_tree_set_double(PNODE_FINFO(pi), value);
5362 
5363 	return pi;
5364 }
5365 
5366 proto_item *
proto_tree_add_double_format_value(proto_tree * tree,int hfindex,tvbuff_t * tvb,gint start,gint length,double value,const char * format,...)5367 proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5368 				   gint start, gint length, double value,
5369 				   const char *format, ...)
5370 {
5371 	proto_item	  *pi;
5372 	va_list		   ap;
5373 
5374 	pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5375 	if (pi != tree) {
5376 		va_start(ap, format);
5377 		proto_tree_set_representation_value(pi, format, ap);
5378 		va_end(ap);
5379 	}
5380 
5381 	return pi;
5382 }
5383 
5384 proto_item *
proto_tree_add_double_format(proto_tree * tree,int hfindex,tvbuff_t * tvb,gint start,gint length,double value,const char * format,...)5385 proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5386 			     gint start, gint length, double value,
5387 			     const char *format, ...)
5388 {
5389 	proto_item	  *pi;
5390 	va_list		   ap;
5391 
5392 	pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5393 	if (pi != tree) {
5394 		TRY_TO_FAKE_THIS_REPR(pi);
5395 
5396 		va_start(ap, format);
5397 		proto_tree_set_representation(pi, format, ap);
5398 		va_end(ap);
5399 	}
5400 
5401 	return pi;
5402 }
5403 
5404 /* Set the FT_DOUBLE value */
5405 static void
proto_tree_set_double(field_info * fi,double value)5406 proto_tree_set_double(field_info *fi, double value)
5407 {
5408 	fvalue_set_floating(&fi->value, value);
5409 }
5410 
5411 /* Add FT_CHAR or FT_UINT{8,16,24,32} to a proto_tree */
5412 proto_item *
proto_tree_add_uint(proto_tree * tree,int hfindex,tvbuff_t * tvb,gint start,gint length,guint32 value)5413 proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
5414 		    gint length, guint32 value)
5415 {
5416 	proto_item	  *pi = NULL;
5417 	header_field_info *hfinfo;
5418 
5419 	CHECK_FOR_NULL_TREE(tree);
5420 
5421 	TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
5422 
5423 	switch (hfinfo->type) {
5424 		case FT_CHAR:
5425 		case FT_UINT8:
5426 		case FT_UINT16:
5427 		case FT_UINT24:
5428 		case FT_UINT32:
5429 		case FT_FRAMENUM:
5430 			pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5431 			proto_tree_set_uint(PNODE_FINFO(pi), value);
5432 			break;
5433 
5434 		default:
5435 			REPORT_DISSECTOR_BUG("field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, FT_UINT32, or FT_FRAMENUM",
5436 			    hfinfo->abbrev);
5437 	}
5438 
5439 	return pi;
5440 }
5441 
5442 proto_item *
proto_tree_add_uint_format_value(proto_tree * tree,int hfindex,tvbuff_t * tvb,gint start,gint length,guint32 value,const char * format,...)5443 proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5444 				 gint start, gint length, guint32 value,
5445 				 const char *format, ...)
5446 {
5447 	proto_item	  *pi;
5448 	va_list		   ap;
5449 
5450 	pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5451 	if (pi != tree) {
5452 		va_start(ap, format);
5453 		proto_tree_set_representation_value(pi, format, ap);
5454 		va_end(ap);
5455 	}
5456 
5457 	return pi;
5458 }
5459 
5460 proto_item *
proto_tree_add_uint_format(proto_tree * tree,int hfindex,tvbuff_t * tvb,gint start,gint length,guint32 value,const char * format,...)5461 proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5462 			   gint start, gint length, guint32 value,
5463 			   const char *format, ...)
5464 {
5465 	proto_item	  *pi;
5466 	va_list		   ap;
5467 
5468 	pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5469 	if (pi != tree) {
5470 		TRY_TO_FAKE_THIS_REPR(pi);
5471 
5472 		va_start(ap, format);
5473 		proto_tree_set_representation(pi, format, ap);
5474 		va_end(ap);
5475 	}
5476 
5477 	return pi;
5478 }
5479 
5480 /* Set the FT_UINT{8,16,24,32} value */
5481 static void
proto_tree_set_uint(field_info * fi,guint32 value)5482 proto_tree_set_uint(field_info *fi, guint32 value)
5483 {
5484 	header_field_info *hfinfo;
5485 	guint32		   integer;
5486 
5487 	hfinfo = fi->hfinfo;
5488 	integer = value;
5489 
5490 	if (hfinfo->bitmask) {
5491 		/* Mask out irrelevant portions */
5492 		integer &= (guint32)(hfinfo->bitmask);
5493 
5494 		/* Shift bits */
5495 		integer >>= hfinfo_bitshift(hfinfo);
5496 
5497 		FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)));
5498 		FI_SET_FLAG(fi, FI_BITS_SIZE(hfinfo_mask_bitwidth(hfinfo)));
5499 	}
5500 
5501 	fvalue_set_uinteger(&fi->value, integer);
5502 }
5503 
5504 /* Add FT_UINT{40,48,56,64} to a proto_tree */
5505 proto_item *
proto_tree_add_uint64(proto_tree * tree,int hfindex,tvbuff_t * tvb,gint start,gint length,guint64 value)5506 proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
5507 		      gint length, guint64 value)
5508 {
5509 	proto_item	  *pi = NULL;
5510 	header_field_info *hfinfo;
5511 
5512 	CHECK_FOR_NULL_TREE(tree);
5513 
5514 	TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
5515 
5516 	switch (hfinfo->type) {
5517 		case FT_UINT40:
5518 		case FT_UINT48:
5519 		case FT_UINT56:
5520 		case FT_UINT64:
5521 		case FT_FRAMENUM:
5522 			pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5523 			proto_tree_set_uint64(PNODE_FINFO(pi), value);
5524 			break;
5525 
5526 		default:
5527 			REPORT_DISSECTOR_BUG("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, FT_UINT64, or FT_FRAMENUM",
5528 			    hfinfo->abbrev);
5529 	}
5530 
5531 	return pi;
5532 }
5533 
5534 proto_item *
proto_tree_add_uint64_format_value(proto_tree * tree,int hfindex,tvbuff_t * tvb,gint start,gint length,guint64 value,const char * format,...)5535 proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5536 				   gint start, gint length, guint64 value,
5537 				   const char *format, ...)
5538 {
5539 	proto_item	  *pi;
5540 	va_list		   ap;
5541 
5542 	pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
5543 	if (pi != tree) {
5544 		va_start(ap, format);
5545 		proto_tree_set_representation_value(pi, format, ap);
5546 		va_end(ap);
5547 	}
5548 
5549 	return pi;
5550 }
5551 
5552 proto_item *
proto_tree_add_uint64_format(proto_tree * tree,int hfindex,tvbuff_t * tvb,gint start,gint length,guint64 value,const char * format,...)5553 proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5554 			     gint start, gint length, guint64 value,
5555 			     const char *format, ...)
5556 {
5557 	proto_item	  *pi;
5558 	va_list		   ap;
5559 
5560 	pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
5561 	if (pi != tree) {
5562 		TRY_TO_FAKE_THIS_REPR(pi);
5563 
5564 		va_start(ap, format);
5565 		proto_tree_set_representation(pi, format, ap);
5566 		va_end(ap);
5567 	}
5568 
5569 	return pi;
5570 }
5571 
5572 /* Set the FT_UINT{40,48,56,64} value */
5573 static void
proto_tree_set_uint64(field_info * fi,guint64 value)5574 proto_tree_set_uint64(field_info *fi, guint64 value)
5575 {
5576 	header_field_info *hfinfo;
5577 	guint64		   integer;
5578 
5579 	hfinfo = fi->hfinfo;
5580 	integer = value;
5581 
5582 	if (hfinfo->bitmask) {
5583 		/* Mask out irrelevant portions */
5584 		integer &= hfinfo->bitmask;
5585 
5586 		/* Shift bits */
5587 		integer >>= hfinfo_bitshift(hfinfo);
5588 
5589 		FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)));
5590 		FI_SET_FLAG(fi, FI_BITS_SIZE(hfinfo_mask_bitwidth(hfinfo)));
5591 	}
5592 
5593 	fvalue_set_uinteger64(&fi->value, integer);
5594 }
5595 
5596 /* Add FT_INT{8,16,24,32} to a proto_tree */
5597 proto_item *
proto_tree_add_int(proto_tree * tree,int hfindex,tvbuff_t * tvb,gint start,gint length,gint32 value)5598 proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
5599 		   gint length, gint32 value)
5600 {
5601 	proto_item	  *pi = NULL;
5602 	header_field_info *hfinfo;
5603 
5604 	CHECK_FOR_NULL_TREE(tree);
5605 
5606 	TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
5607 
5608 	switch (hfinfo->type) {
5609 		case FT_INT8:
5610 		case FT_INT16:
5611 		case FT_INT24:
5612 		case FT_INT32:
5613 			pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5614 			proto_tree_set_int(PNODE_FINFO(pi), value);
5615 			break;
5616 
5617 		default:
5618 			REPORT_DISSECTOR_BUG("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32",
5619 			    hfinfo->abbrev);
5620 	}
5621 
5622 	return pi;
5623 }
5624 
5625 proto_item *
proto_tree_add_int_format_value(proto_tree * tree,int hfindex,tvbuff_t * tvb,gint start,gint length,gint32 value,const char * format,...)5626 proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5627 				gint start, gint length, gint32 value,
5628 				const char *format, ...)
5629 {
5630 	proto_item  *pi;
5631 	va_list	     ap;
5632 
5633 	pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
5634 	if (pi != tree) {
5635 		va_start(ap, format);
5636 		proto_tree_set_representation_value(pi, format, ap);
5637 		va_end(ap);
5638 	}
5639 
5640 	return pi;
5641 }
5642 
5643 proto_item *
proto_tree_add_int_format(proto_tree * tree,int hfindex,tvbuff_t * tvb,gint start,gint length,gint32 value,const char * format,...)5644 proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5645 			  gint start, gint length, gint32 value,
5646 			  const char *format, ...)
5647 {
5648 	proto_item *pi;
5649 	va_list     ap;
5650 
5651 	pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
5652 	if (pi != tree) {
5653 		TRY_TO_FAKE_THIS_REPR(pi);
5654 
5655 		va_start(ap, format);
5656 		proto_tree_set_representation(pi, format, ap);
5657 		va_end(ap);
5658 	}
5659 
5660 	return pi;
5661 }
5662 
5663 /* Set the FT_INT{8,16,24,32} value */
5664 static void
proto_tree_set_int(field_info * fi,gint32 value)5665 proto_tree_set_int(field_info *fi, gint32 value)
5666 {
5667 	header_field_info *hfinfo;
5668 	guint32		   integer;
5669 	gint		   no_of_bits;
5670 
5671 	hfinfo = fi->hfinfo;
5672 	integer = (guint32) value;
5673 
5674 	if (hfinfo->bitmask) {
5675 		/* Mask out irrelevant portions */
5676 		integer &= (guint32)(hfinfo->bitmask);
5677 
5678 		/* Shift bits */
5679 		integer >>= hfinfo_bitshift(hfinfo);
5680 
5681 		no_of_bits = ws_count_ones(hfinfo->bitmask);
5682 		integer = ws_sign_ext32(integer, no_of_bits);
5683 
5684 		FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)));
5685 		FI_SET_FLAG(fi, FI_BITS_SIZE(hfinfo_mask_bitwidth(hfinfo)));
5686 	}
5687 
5688 	fvalue_set_sinteger(&fi->value, integer);
5689 }
5690 
5691 /* Add FT_INT{40,48,56,64} to a proto_tree */
5692 proto_item *
proto_tree_add_int64(proto_tree * tree,int hfindex,tvbuff_t * tvb,gint start,gint length,gint64 value)5693 proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
5694 		     gint length, gint64 value)
5695 {
5696 	proto_item	  *pi = NULL;
5697 	header_field_info *hfinfo;
5698 
5699 	CHECK_FOR_NULL_TREE(tree);
5700 
5701 	TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
5702 
5703 	switch (hfinfo->type) {
5704 		case FT_INT40:
5705 		case FT_INT48:
5706 		case FT_INT56:
5707 		case FT_INT64:
5708 			pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5709 			proto_tree_set_int64(PNODE_FINFO(pi), value);
5710 			break;
5711 
5712 		default:
5713 			REPORT_DISSECTOR_BUG("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64",
5714 			    hfinfo->abbrev);
5715 	}
5716 
5717 	return pi;
5718 }
5719 
5720 proto_item *
proto_tree_add_int64_format_value(proto_tree * tree,int hfindex,tvbuff_t * tvb,gint start,gint length,gint64 value,const char * format,...)5721 proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5722 				  gint start, gint length, gint64 value,
5723 				  const char *format, ...)
5724 {
5725 	proto_item	  *pi;
5726 	va_list		   ap;
5727 
5728 	pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
5729 	if (pi != tree) {
5730 		va_start(ap, format);
5731 		proto_tree_set_representation_value(pi, format, ap);
5732 		va_end(ap);
5733 	}
5734 
5735 	return pi;
5736 }
5737 
5738 /* Set the FT_INT{40,48,56,64} value */
5739 static void
proto_tree_set_int64(field_info * fi,gint64 value)5740 proto_tree_set_int64(field_info *fi, gint64 value)
5741 {
5742 	header_field_info *hfinfo;
5743 	guint64		   integer;
5744 	gint		   no_of_bits;
5745 
5746 	hfinfo = fi->hfinfo;
5747 	integer = value;
5748 
5749 	if (hfinfo->bitmask) {
5750 		/* Mask out irrelevant portions */
5751 		integer &= hfinfo->bitmask;
5752 
5753 		/* Shift bits */
5754 		integer >>= hfinfo_bitshift(hfinfo);
5755 
5756 		no_of_bits = ws_count_ones(hfinfo->bitmask);
5757 		integer = ws_sign_ext64(integer, no_of_bits);
5758 
5759 		FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)));
5760 		FI_SET_FLAG(fi, FI_BITS_SIZE(hfinfo_mask_bitwidth(hfinfo)));
5761 	}
5762 
5763 	fvalue_set_sinteger64(&fi->value, integer);
5764 }
5765 
5766 proto_item *
proto_tree_add_int64_format(proto_tree * tree,int hfindex,tvbuff_t * tvb,gint start,gint length,gint64 value,const char * format,...)5767 proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5768 			   gint start, gint length, gint64 value,
5769 			   const char *format, ...)
5770 {
5771 	proto_item	  *pi;
5772 	va_list		   ap;
5773 
5774 	pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
5775 	if (pi != tree) {
5776 		TRY_TO_FAKE_THIS_REPR(pi);
5777 
5778 		va_start(ap, format);
5779 		proto_tree_set_representation(pi, format, ap);
5780 		va_end(ap);
5781 	}
5782 
5783 	return pi;
5784 }
5785 
5786 /* Add a FT_EUI64 to a proto_tree */
5787 proto_item *
proto_tree_add_eui64(proto_tree * tree,int hfindex,tvbuff_t * tvb,gint start,gint length,const guint64 value)5788 proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
5789 		     gint length, const guint64 value)
5790 {
5791 	proto_item	  *pi;
5792 	header_field_info *hfinfo;
5793 
5794 	CHECK_FOR_NULL_TREE(tree);
5795 
5796 	TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
5797 
5798 	DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_EUI64);
5799 
5800 	pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5801 	proto_tree_set_eui64(PNODE_FINFO(pi), value);
5802 
5803 	return pi;
5804 }
5805 
5806 proto_item *
proto_tree_add_eui64_format_value(proto_tree * tree,int hfindex,tvbuff_t * tvb,gint start,gint length,const guint64 value,const char * format,...)5807 proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5808 				  gint start, gint length, const guint64 value,
5809 				  const char *format, ...)
5810 {
5811 	proto_item	  *pi;
5812 	va_list		   ap;
5813 
5814 	pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
5815 	if (pi != tree) {
5816 		va_start(ap, format);
5817 		proto_tree_set_representation_value(pi, format, ap);
5818 		va_end(ap);
5819 	}
5820 
5821 	return pi;
5822 }
5823 
5824 proto_item *
proto_tree_add_eui64_format(proto_tree * tree,int hfindex,tvbuff_t * tvb,gint start,gint length,const guint64 value,const char * format,...)5825 proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5826 			    gint start, gint length, const guint64 value,
5827 			    const char *format, ...)
5828 {
5829 	proto_item	  *pi;
5830 	va_list		   ap;
5831 
5832 	pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
5833 	if (pi != tree) {
5834 		TRY_TO_FAKE_THIS_REPR(pi);
5835 
5836 		va_start(ap, format);
5837 		proto_tree_set_representation(pi, format, ap);
5838 		va_end(ap);
5839 	}
5840 
5841 	return pi;
5842 }
5843 
5844 /* Set the FT_EUI64 value */
5845 static void
proto_tree_set_eui64(field_info * fi,const guint64 value)5846 proto_tree_set_eui64(field_info *fi, const guint64 value)
5847 {
5848 	fvalue_set_uinteger64(&fi->value, value);
5849 }
5850 static void
proto_tree_set_eui64_tvb(field_info * fi,tvbuff_t * tvb,gint start,const guint encoding)5851 proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, gint start, const guint encoding)
5852 {
5853 	if (encoding)
5854 	{
5855 		proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
5856 	} else {
5857 		proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
5858 	}
5859 }
5860 
5861 /* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
5862 static proto_item *
proto_tree_add_node(proto_tree * tree,field_info * fi)5863 proto_tree_add_node(proto_tree *tree, field_info *fi)
5864 {
5865 	proto_node *pnode, *tnode, *sibling;
5866 	field_info *tfi;
5867 	guint depth = 1;
5868 
5869 	/*
5870 	 * Restrict our depth. proto_tree_traverse_pre_order and
5871 	 * proto_tree_traverse_post_order (and possibly others) are recursive
5872 	 * so we need to be mindful of our stack size.
5873 	 */
5874 	if (tree->first_child == NULL) {
5875 		for (tnode = tree; tnode != NULL; tnode = tnode->parent) {
5876 			depth++;
5877 			if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)) {
5878 				THROW_MESSAGE(DissectorError, wmem_strdup_printf(PNODE_POOL(tree),
5879 						     "Maximum tree depth %d exceeded for \"%s\" - \"%s\" (%s:%u) (Maximum depth can be increased in advanced preferences)",
5880 						     prefs.gui_max_tree_depth,
5881 						     fi->hfinfo->name, fi->hfinfo->abbrev, G_STRFUNC, __LINE__));
5882 			}
5883 		}
5884 	}
5885 
5886 	/*
5887 	 * Make sure "tree" is ready to have subtrees under it, by
5888 	 * checking whether it's been given an ett_ value.
5889 	 *
5890 	 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
5891 	 * node of the protocol tree.  That node is not displayed,
5892 	 * so it doesn't need an ett_ value to remember whether it
5893 	 * was expanded.
5894 	 */
5895 	tnode = tree;
5896 	tfi = PNODE_FINFO(tnode);
5897 	if (tfi != NULL && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
5898 		REPORT_DISSECTOR_BUG("\"%s\" - \"%s\" tfi->tree_type: %d invalid (%s:%u)",
5899 				     fi->hfinfo->name, fi->hfinfo->abbrev, tfi->tree_type, __FILE__, __LINE__);
5900 		/* XXX - is it safe to continue here? */
5901 	}
5902 
5903 	pnode = wmem_new(PNODE_POOL(tree), proto_node);
5904 	PROTO_NODE_INIT(pnode);
5905 	pnode->parent = tnode;
5906 	PNODE_FINFO(pnode) = fi;
5907 	pnode->tree_data = PTREE_DATA(tree);
5908 
5909 	if (tnode->last_child != NULL) {
5910 		sibling = tnode->last_child;
5911 		DISSECTOR_ASSERT(sibling->next == NULL);
5912 		sibling->next = pnode;
5913 	} else
5914 		tnode->first_child = pnode;
5915 	tnode->last_child = pnode;
5916 
5917 	tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
5918 
5919 	return (proto_item *)pnode;
5920 }
5921 
5922 
5923 /* Generic way to allocate field_info and add to proto_tree.
5924  * Sets *pfi to address of newly-allocated field_info struct */
5925 static proto_item *
proto_tree_add_pi(proto_tree * tree,header_field_info * hfinfo,tvbuff_t * tvb,gint start,gint * length)5926 proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, gint start,
5927 		  gint *length)
5928 {
5929 	proto_item *pi;
5930 	field_info *fi;
5931 	gint		item_length;
5932 
5933 	get_hfi_length(hfinfo, tvb, start, length, &item_length, ENC_NA);
5934 	fi = new_field_info(tree, hfinfo, tvb, start, item_length);
5935 	pi = proto_tree_add_node(tree, fi);
5936 
5937 	return pi;
5938 }
5939 
5940 
5941 static void
get_hfi_length(header_field_info * hfinfo,tvbuff_t * tvb,const gint start,gint * length,gint * item_length,const guint encoding)5942 get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start, gint *length,
5943 		   gint *item_length, const guint encoding)
5944 {
5945 	gint length_remaining;
5946 
5947 	/*
5948 	 * We only allow a null tvbuff if the item has a zero length,
5949 	 * i.e. if there's no data backing it.
5950 	 */
5951 	DISSECTOR_ASSERT(tvb != NULL || *length == 0);
5952 
5953 	/*
5954 	 * XXX - in some protocols, there are 32-bit unsigned length
5955 	 * fields, so lengths in protocol tree and tvbuff routines
5956 	 * should really be unsigned.  We should have, for those
5957 	 * field types for which "to the end of the tvbuff" makes sense,
5958 	 * additional routines that take no length argument and
5959 	 * add fields that run to the end of the tvbuff.
5960 	 */
5961 	if (*length == -1) {
5962 		/*
5963 		 * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING,
5964 		 * FT_STRINGZPAD, and FT_STRINGZTRUNC fields, a length
5965 		 * of -1 means "set the length to what remains in the
5966 		 * tvbuff".
5967 		 *
5968 		 * The assumption is either that
5969 		 *
5970 		 *	1) the length of the item can only be determined
5971 		 *	   by dissection (typically true of items with
5972 		 *	   subitems, which are probably FT_NONE or
5973 		 *	   FT_PROTOCOL)
5974 		 *
5975 		 * or
5976 		 *
5977 		 *	2) if the tvbuff is "short" (either due to a short
5978 		 *	   snapshot length or due to lack of reassembly of
5979 		 *	   fragments/segments/whatever), we want to display
5980 		 *	   what's available in the field (probably FT_BYTES
5981 		 *	   or FT_STRING) and then throw an exception later
5982 		 *
5983 		 * or
5984 		 *
5985 		 *	3) the field is defined to be "what's left in the
5986 		 *	   packet"
5987 		 *
5988 		 * so we set the length to what remains in the tvbuff so
5989 		 * that, if we throw an exception while dissecting, it
5990 		 * has what is probably the right value.
5991 		 *
5992 		 * For FT_STRINGZ, it means "the string is null-terminated,
5993 		 * not null-padded; set the length to the actual length
5994 		 * of the string", and if the tvbuff if short, we just
5995 		 * throw an exception.
5996 		 *
5997 		 * For ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC|ENC_VARIANT_ZIGZAG, it means "find the end of the string",
5998 		 * and if the tvbuff if short, we just throw an exception.
5999 		 *
6000 		 * It's not valid for any other type of field.  For those
6001 		 * fields, we treat -1 the same way we treat other
6002 		 * negative values - we assume the length is a Really
6003 		 * Big Positive Number, and throw a ReportedBoundsError
6004 		 * exception, under the assumption that the Really Big
6005 		 * Length would run past the end of the packet.
6006 		 */
6007 		if ((IS_FT_INT(hfinfo->type)) || (IS_FT_UINT(hfinfo->type))) {
6008 			if (encoding & (ENC_VARINT_PROTOBUF|ENC_VARINT_ZIGZAG)) {
6009 				/*
6010 				 * Leave the length as -1, so our caller knows
6011 				 * it was -1.
6012 				 */
6013 				*item_length = *length;
6014 				return;
6015 			} else if (encoding & ENC_VARINT_QUIC) {
6016 				switch (tvb_get_guint8(tvb, start) >> 6)
6017 				{
6018 				case 0: /* 0b00 => 1 byte length (6 bits Usable) */
6019 					*item_length = 1;
6020 					break;
6021 				case 1: /* 0b01 => 2 bytes length (14 bits Usable) */
6022 					*item_length = 2;
6023 					break;
6024 				case 2: /* 0b10 => 4 bytes length (30 bits Usable) */
6025 					*item_length = 4;
6026 					break;
6027 				case 3: /* 0b11 => 8 bytes length (62 bits Usable) */
6028 					*item_length = 8;
6029 					break;
6030 				}
6031 			}
6032 		}
6033 
6034 		switch (hfinfo->type) {
6035 
6036 		case FT_PROTOCOL:
6037 		case FT_NONE:
6038 		case FT_BYTES:
6039 		case FT_STRING:
6040 		case FT_STRINGZPAD:
6041 		case FT_STRINGZTRUNC:
6042 			/*
6043 			 * We allow FT_PROTOCOLs to be zero-length -
6044 			 * for example, an ONC RPC NULL procedure has
6045 			 * neither arguments nor reply, so the
6046 			 * payload for that protocol is empty.
6047 			 *
6048 			 * We also allow the others to be zero-length -
6049 			 * because that's the way the code has been for a
6050 			 * long, long time.
6051 			 *
6052 			 * However, we want to ensure that the start
6053 			 * offset is not *past* the byte past the end
6054 			 * of the tvbuff: we throw an exception in that
6055 			 * case.
6056 			 */
6057 			*length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
6058 			DISSECTOR_ASSERT(*length >= 0);
6059 			break;
6060 
6061 		case FT_STRINGZ:
6062 			/*
6063 			 * Leave the length as -1, so our caller knows
6064 			 * it was -1.
6065 			 */
6066 			break;
6067 
6068 		default:
6069 			THROW(ReportedBoundsError);
6070 			DISSECTOR_ASSERT_NOT_REACHED();
6071 		}
6072 		*item_length = *length;
6073 	} else {
6074 		*item_length = *length;
6075 		if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6076 			/*
6077 			 * These types are for interior nodes of the
6078 			 * tree, and don't have data associated with
6079 			 * them; if the length is negative (XXX - see
6080 			 * above) or goes past the end of the tvbuff,
6081 			 * cut it short at the end of the tvbuff.
6082 			 * That way, if this field is selected in
6083 			 * Wireshark, we don't highlight stuff past
6084 			 * the end of the data.
6085 			 */
6086 			/* XXX - what to do, if we don't have a tvb? */
6087 			if (tvb) {
6088 				length_remaining = tvb_captured_length_remaining(tvb, start);
6089 				if (*item_length < 0 ||
6090 					(*item_length > 0 &&
6091 					  (length_remaining < *item_length)))
6092 					*item_length = length_remaining;
6093 			}
6094 		}
6095 		if (*item_length < 0) {
6096 			THROW(ReportedBoundsError);
6097 		}
6098 	}
6099 }
6100 
6101 static gint
get_full_length(header_field_info * hfinfo,tvbuff_t * tvb,const gint start,gint length,guint item_length,const gint encoding)6102 get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start,
6103 		gint length, guint item_length, const gint encoding)
6104 {
6105 	guint32 n;
6106 
6107 	/*
6108 	 * We need to get the correct item length here.
6109 	 * That's normally done by proto_tree_new_item(),
6110 	 * but we won't be calling it.
6111 	 */
6112 	switch (hfinfo->type) {
6113 
6114 	case FT_NONE:
6115 	case FT_PROTOCOL:
6116 	case FT_BYTES:
6117 		/*
6118 		 * The length is the specified length.
6119 		 */
6120 		break;
6121 
6122 	case FT_UINT_BYTES:
6123 		n = get_uint_value(NULL, tvb, start, length, encoding);
6124 		item_length += n;
6125 		break;
6126 
6127 	/* XXX - make these just FT_UINT? */
6128 	case FT_UINT8:
6129 	case FT_UINT16:
6130 	case FT_UINT24:
6131 	case FT_UINT32:
6132 	case FT_UINT40:
6133 	case FT_UINT48:
6134 	case FT_UINT56:
6135 	case FT_UINT64:
6136 	/* XXX - make these just FT_INT? */
6137 	case FT_INT8:
6138 	case FT_INT16:
6139 	case FT_INT24:
6140 	case FT_INT32:
6141 	case FT_INT40:
6142 	case FT_INT48:
6143 	case FT_INT56:
6144 	case FT_INT64:
6145 		if (encoding & (ENC_VARIANT_MASK)) {
6146 			if (length < -1) {
6147 				report_type_length_mismatch(NULL, "a FT_[U]INT", length, TRUE);
6148 			}
6149 			if (length == -1) {
6150 				guint64 dummy;
6151 				/* This can throw an exception */
6152 				/* XXX - do this without fetching the varint? */
6153 				length = tvb_get_varint(tvb, start, FT_VARINT_MAX_LEN, &dummy, encoding);
6154 				if (length == 0) {
6155 					THROW(ReportedBoundsError);
6156 				}
6157 			}
6158 			item_length = length;
6159 			break;
6160 		}
6161 
6162 		/*
6163 		 * The length is the specified length.
6164 		 */
6165 		break;
6166 
6167 	case FT_BOOLEAN:
6168 	case FT_CHAR:
6169 	case FT_IPv4:
6170 	case FT_IPXNET:
6171 	case FT_IPv6:
6172 	case FT_FCWWN:
6173 	case FT_AX25:
6174 	case FT_VINES:
6175 	case FT_ETHER:
6176 	case FT_EUI64:
6177 	case FT_GUID:
6178 	case FT_OID:
6179 	case FT_REL_OID:
6180 	case FT_SYSTEM_ID:
6181 	case FT_FLOAT:
6182 	case FT_DOUBLE:
6183 	case FT_STRING:
6184 		/*
6185 		 * The length is the specified length.
6186 		 */
6187 		break;
6188 
6189 	case FT_STRINGZ:
6190 		if (length < -1) {
6191 			report_type_length_mismatch(NULL, "a string", length, TRUE);
6192 		}
6193 		if (length == -1) {
6194 			/* This can throw an exception */
6195 			/* XXX - do this without fetching the string? */
6196 			wmem_free(NULL, tvb_get_stringz_enc(NULL, tvb, start, &length, encoding));
6197 		}
6198 		item_length = length;
6199 		break;
6200 
6201 	case FT_UINT_STRING:
6202 		n = get_uint_value(NULL, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK);
6203 		item_length += n;
6204 		break;
6205 
6206 	case FT_STRINGZPAD:
6207 	case FT_STRINGZTRUNC:
6208 	case FT_ABSOLUTE_TIME:
6209 	case FT_RELATIVE_TIME:
6210 	case FT_IEEE_11073_SFLOAT:
6211 	case FT_IEEE_11073_FLOAT:
6212 		/*
6213 		 * The length is the specified length.
6214 		 */
6215 		break;
6216 
6217 	default:
6218 		REPORT_DISSECTOR_BUG("field %s has type %d (%s) not handled in gset_full_length()",
6219 				     hfinfo->abbrev,
6220 				     hfinfo->type,
6221 				     ftype_name(hfinfo->type));
6222 		break;
6223 	}
6224 	return item_length;
6225 }
6226 
6227 static field_info *
new_field_info(proto_tree * tree,header_field_info * hfinfo,tvbuff_t * tvb,const gint start,const gint item_length)6228 new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
6229 	       const gint start, const gint item_length)
6230 {
6231 	field_info *fi;
6232 
6233 	FIELD_INFO_NEW(PNODE_POOL(tree), fi);
6234 
6235 	fi->hfinfo     = hfinfo;
6236 	fi->start      = start;
6237 	fi->start     += (tvb)?tvb_raw_offset(tvb):0;
6238 	fi->length     = item_length;
6239 	fi->tree_type  = -1;
6240 	fi->flags      = 0;
6241 	if (!PTREE_DATA(tree)->visible)
6242 		FI_SET_FLAG(fi, FI_HIDDEN);
6243 	fvalue_init(&fi->value, fi->hfinfo->type);
6244 	fi->rep        = NULL;
6245 
6246 	/* add the data source tvbuff */
6247 	fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL;
6248 
6249 	fi->appendix_start  = 0;
6250 	fi->appendix_length = 0;
6251 
6252 	return fi;
6253 }
6254 
6255 /* If the protocol tree is to be visible, set the representation of a
6256    proto_tree entry with the name of the field for the item and with
6257    the value formatted with the supplied printf-style format and
6258    argument list. */
6259 static void
proto_tree_set_representation_value(proto_item * pi,const char * format,va_list ap)6260 proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
6261 {
6262 	ws_assert(pi);
6263 
6264 	/* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
6265 	 * items string representation */
6266 	if (PTREE_DATA(pi)->visible && !proto_item_is_hidden(pi)) {
6267 		int               ret = 0;
6268 		field_info        *fi = PITEM_FINFO(pi);
6269 		header_field_info *hf;
6270 
6271 		DISSECTOR_ASSERT(fi);
6272 
6273 		hf = fi->hfinfo;
6274 
6275 		ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
6276 		if (hf->bitmask && (hf->type == FT_BOOLEAN || IS_FT_UINT(hf->type))) {
6277 			guint64 val;
6278 			char *p;
6279 
6280 			if (IS_FT_UINT32(hf->type))
6281 				val = fvalue_get_uinteger(&fi->value);
6282 			else
6283 				val = fvalue_get_uinteger64(&fi->value);
6284 
6285 			val <<= hfinfo_bitshift(hf);
6286 
6287 			p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
6288 			ret = (int) (p - fi->rep->representation);
6289 		}
6290 
6291 		/* put in the hf name */
6292 		ret += g_snprintf(fi->rep->representation + ret, ITEM_LABEL_LENGTH - ret, "%s: ", hf->name);
6293 
6294 		/* If possible, Put in the value of the string */
6295 		if (ret < ITEM_LABEL_LENGTH) {
6296 			ret += g_vsnprintf(fi->rep->representation + ret,
6297 					  ITEM_LABEL_LENGTH - ret, format, ap);
6298 		}
6299 		if (ret >= ITEM_LABEL_LENGTH) {
6300 			/* Uh oh, we don't have enough room.  Tell the user
6301 			 * that the field is truncated.
6302 			 */
6303 			LABEL_MARK_TRUNCATED_START(fi->rep->representation);
6304 		}
6305 	}
6306 }
6307 
6308 /* If the protocol tree is to be visible, set the representation of a
6309    proto_tree entry with the representation formatted with the supplied
6310    printf-style format and argument list. */
6311 static void
proto_tree_set_representation(proto_item * pi,const char * format,va_list ap)6312 proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
6313 {
6314 	int	    ret;	/*tmp return value */
6315 	field_info *fi = PITEM_FINFO(pi);
6316 
6317 	DISSECTOR_ASSERT(fi);
6318 
6319 	if (!proto_item_is_hidden(pi)) {
6320 		ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
6321 		ret = g_vsnprintf(fi->rep->representation, ITEM_LABEL_LENGTH,
6322 				  format, ap);
6323 		if (ret >= ITEM_LABEL_LENGTH) {
6324 			/* Uh oh, we don't have enough room.  Tell the user
6325 			 * that the field is truncated.
6326 			 */
6327 			LABEL_MARK_TRUNCATED_START(fi->rep->representation);
6328 		}
6329 	}
6330 }
6331 
6332 static int
protoo_strlcpy(gchar * dest,const gchar * src,gsize dest_size)6333 protoo_strlcpy(gchar *dest, const gchar *src, gsize dest_size)
6334 {
6335 	gsize res = g_strlcpy(dest, src, dest_size);
6336 
6337 	if (res > dest_size)
6338 		res = dest_size;
6339 	return (int) res;
6340 }
6341 
6342 static header_field_info *
hfinfo_same_name_get_prev(const header_field_info * hfinfo)6343 hfinfo_same_name_get_prev(const header_field_info *hfinfo)
6344 {
6345 	header_field_info *dup_hfinfo;
6346 
6347 	if (hfinfo->same_name_prev_id == -1)
6348 		return NULL;
6349 	PROTO_REGISTRAR_GET_NTH(hfinfo->same_name_prev_id, dup_hfinfo);
6350 	return dup_hfinfo;
6351 }
6352 
6353 static void
hfinfo_remove_from_gpa_name_map(const header_field_info * hfinfo)6354 hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
6355 {
6356 	g_free(last_field_name);
6357 	last_field_name = NULL;
6358 
6359 	if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
6360 		/* No hfinfo with the same name */
6361 		g_hash_table_steal(gpa_name_map, hfinfo->abbrev);
6362 		return;
6363 	}
6364 
6365 	if (hfinfo->same_name_next) {
6366 		hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
6367 	}
6368 
6369 	if (hfinfo->same_name_prev_id != -1) {
6370 		header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
6371 		same_name_prev->same_name_next = hfinfo->same_name_next;
6372 		if (!hfinfo->same_name_next) {
6373 			/* It's always the latest added hfinfo which is stored in gpa_name_map */
6374 			g_hash_table_insert(gpa_name_map, (gpointer) (same_name_prev->abbrev), same_name_prev);
6375 		}
6376 	}
6377 }
6378 
6379 int
proto_item_fill_display_label(field_info * finfo,gchar * display_label_str,const int label_str_size)6380 proto_item_fill_display_label(field_info *finfo, gchar *display_label_str, const int label_str_size)
6381 {
6382 	header_field_info *hfinfo = finfo->hfinfo;
6383 	int label_len = 0;
6384 	char *tmp_str;
6385 	guint8 *bytes;
6386 	guint32 number;
6387 	guint64 number64;
6388 	const true_false_string  *tfstring;
6389 	const char *hf_str_val;
6390 	char number_buf[48];
6391 	const char *number_out;
6392 	address addr;
6393 	ws_in4_addr ipv4;
6394 	ws_in6_addr *ipv6;
6395 
6396 	switch (hfinfo->type) {
6397 
6398 		case FT_NONE:
6399 		case FT_PROTOCOL:
6400 			return protoo_strlcpy(display_label_str, UTF8_CHECK_MARK, label_str_size);
6401 
6402 		case FT_UINT_BYTES:
6403 		case FT_BYTES:
6404 			tmp_str = hfinfo_format_bytes(NULL,
6405 				hfinfo,
6406 				(guint8 *)fvalue_get(&finfo->value),
6407 				fvalue_length(&finfo->value));
6408 			label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
6409 			wmem_free(NULL, tmp_str);
6410 			break;
6411 
6412 		case FT_ABSOLUTE_TIME:
6413 			tmp_str = abs_time_to_str(NULL, (const nstime_t *)fvalue_get(&finfo->value), (absolute_time_display_e)hfinfo->display, TRUE);
6414 			label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
6415 			wmem_free(NULL, tmp_str);
6416 			break;
6417 
6418 		case FT_RELATIVE_TIME:
6419 			tmp_str = rel_time_to_secs_str(NULL, (const nstime_t *)fvalue_get(&finfo->value));
6420 			label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
6421 			wmem_free(NULL, tmp_str);
6422 			break;
6423 
6424 		case FT_BOOLEAN:
6425 			number64 = fvalue_get_uinteger64(&finfo->value);
6426 			tfstring = &tfs_true_false;
6427 			if (hfinfo->strings) {
6428 				tfstring = (const struct true_false_string*) hfinfo->strings;
6429 			}
6430 			label_len = protoo_strlcpy(display_label_str,
6431 					tfs_get_string(!!number64, tfstring), label_str_size);
6432 			break;
6433 
6434 		case FT_CHAR:
6435 			number = fvalue_get_uinteger(&finfo->value);
6436 
6437 			if (FIELD_DISPLAY(hfinfo->display) == BASE_CUSTOM) {
6438 				gchar tmp[ITEM_LABEL_LENGTH];
6439 				custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
6440 
6441 				DISSECTOR_ASSERT(fmtfunc);
6442 				fmtfunc(tmp, number);
6443 
6444 				label_len = protoo_strlcpy(display_label_str, tmp, label_str_size);
6445 
6446 			} else if (hfinfo->strings) {
6447 				number_out = hf_try_val_to_str(number, hfinfo);
6448 
6449 				if (!number_out) {
6450 					number_out = hfinfo_char_value_format_display(BASE_HEX, number_buf, number);
6451 				}
6452 
6453 				label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
6454 
6455 			} else {
6456 				number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
6457 
6458 				label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
6459 			}
6460 
6461 			break;
6462 
6463 		/* XXX - make these just FT_NUMBER? */
6464 		case FT_INT8:
6465 		case FT_INT16:
6466 		case FT_INT24:
6467 		case FT_INT32:
6468 		case FT_UINT8:
6469 		case FT_UINT16:
6470 		case FT_UINT24:
6471 		case FT_UINT32:
6472 		case FT_FRAMENUM:
6473 			hf_str_val = NULL;
6474 			number = IS_FT_INT(hfinfo->type) ?
6475 				(guint32) fvalue_get_sinteger(&finfo->value) :
6476 				fvalue_get_uinteger(&finfo->value);
6477 
6478 			if (FIELD_DISPLAY(hfinfo->display) == BASE_CUSTOM) {
6479 				gchar tmp[ITEM_LABEL_LENGTH];
6480 				custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
6481 
6482 				DISSECTOR_ASSERT(fmtfunc);
6483 				fmtfunc(tmp, number);
6484 
6485 				label_len = protoo_strlcpy(display_label_str, tmp, label_str_size);
6486 
6487 			} else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
6488 				if (hfinfo->display & BASE_UNIT_STRING) {
6489 					number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
6490 					label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
6491 					hf_str_val = hf_try_val_to_str(number, hfinfo);
6492 					label_len += protoo_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
6493 				} else {
6494 					number_out = hf_try_val_to_str(number, hfinfo);
6495 
6496 					if (!number_out) {
6497 						number_out = hfinfo_number_value_format_display(hfinfo, hfinfo->display, number_buf, number);
6498 					}
6499 
6500 					label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
6501 				}
6502 			} else {
6503 				number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
6504 
6505 				label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
6506 			}
6507 
6508 			break;
6509 
6510 		case FT_INT40:
6511 		case FT_INT48:
6512 		case FT_INT56:
6513 		case FT_INT64:
6514 		case FT_UINT40:
6515 		case FT_UINT48:
6516 		case FT_UINT56:
6517 		case FT_UINT64:
6518 			hf_str_val = NULL;
6519 			number64 = IS_FT_INT(hfinfo->type) ?
6520 				(guint64) fvalue_get_sinteger64(&finfo->value) :
6521 				fvalue_get_uinteger64(&finfo->value);
6522 
6523 			if (FIELD_DISPLAY(hfinfo->display) == BASE_CUSTOM) {
6524 				gchar tmp[ITEM_LABEL_LENGTH];
6525 				custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
6526 
6527 				DISSECTOR_ASSERT(fmtfunc64);
6528 				fmtfunc64(tmp, number64);
6529 
6530 				label_len = protoo_strlcpy(display_label_str, tmp, label_str_size);
6531 			} else if (hfinfo->strings) {
6532 				if (hfinfo->display & BASE_UNIT_STRING) {
6533 					number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
6534 					label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
6535 					hf_str_val = hf_try_val64_to_str(number64, hfinfo);
6536 					label_len += protoo_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
6537 				} else {
6538 					number_out = hf_try_val64_to_str(number64, hfinfo);
6539 
6540 					if (!number_out)
6541 						number_out = hfinfo_number_value_format_display64(hfinfo, hfinfo->display, number_buf, number64);
6542 
6543 					label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
6544 				}
6545 			} else {
6546 				number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
6547 
6548 				label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
6549 			}
6550 
6551 			break;
6552 
6553 		case FT_EUI64:
6554 			tmp_str = eui64_to_str(NULL, fvalue_get_uinteger64(&finfo->value));
6555 			label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
6556 			wmem_free(NULL, tmp_str);
6557 			break;
6558 
6559 		case FT_IPv4:
6560 			ipv4 = fvalue_get_uinteger(&finfo->value);
6561 			set_address (&addr, AT_IPv4, 4, &ipv4);
6562 			address_to_str_buf(&addr, display_label_str, label_str_size);
6563 			label_len = (int)strlen(display_label_str);
6564 			break;
6565 
6566 		case FT_IPv6:
6567 			ipv6 = (ws_in6_addr *)fvalue_get(&finfo->value);
6568 			set_address (&addr, AT_IPv6, sizeof(ws_in6_addr), ipv6);
6569 			address_to_str_buf(&addr, display_label_str, label_str_size);
6570 			label_len = (int)strlen(display_label_str);
6571 			break;
6572 
6573 		case FT_FCWWN:
6574 			set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN, fvalue_get(&finfo->value));
6575 			address_to_str_buf(&addr, display_label_str, label_str_size);
6576 			label_len = (int)strlen(display_label_str);
6577 			break;
6578 
6579 		case FT_ETHER:
6580 			set_address (&addr, AT_ETHER, FT_ETHER_LEN, fvalue_get(&finfo->value));
6581 			address_to_str_buf(&addr, display_label_str, label_str_size);
6582 			label_len = (int)strlen(display_label_str);
6583 			break;
6584 
6585 		case FT_GUID:
6586 			tmp_str = guid_to_str(NULL, (e_guid_t *)fvalue_get(&finfo->value));
6587 			label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
6588 			wmem_free(NULL, tmp_str);
6589 			break;
6590 
6591 		case FT_REL_OID:
6592 			bytes = (guint8 *)fvalue_get(&finfo->value);
6593 			tmp_str = rel_oid_resolved_from_encoded(NULL, bytes, fvalue_length(&finfo->value));
6594 			label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
6595 			wmem_free(NULL, tmp_str);
6596 			break;
6597 
6598 		case FT_OID:
6599 			bytes = (guint8 *)fvalue_get(&finfo->value);
6600 			tmp_str = oid_resolved_from_encoded(NULL, bytes, fvalue_length(&finfo->value));
6601 			label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
6602 			wmem_free(NULL, tmp_str);
6603 			break;
6604 
6605 		case FT_SYSTEM_ID:
6606 			bytes = (guint8 *)fvalue_get(&finfo->value);
6607 			tmp_str = print_system_id(NULL, bytes, fvalue_length(&finfo->value));
6608 			label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
6609 			wmem_free(NULL, tmp_str);
6610 			break;
6611 
6612 		case FT_FLOAT:
6613 			if (hfinfo->display & BASE_UNIT_STRING) {
6614 				double d_value = fvalue_get_floating(&finfo->value);
6615 				g_snprintf(display_label_str, label_str_size,
6616 						"%." G_STRINGIFY(FLT_DIG) "g%s", d_value,
6617 						unit_name_string_get_double(d_value, (const unit_name_string*)hfinfo->strings));
6618 			} else {
6619 				g_snprintf(display_label_str, label_str_size,
6620 						"%." G_STRINGIFY(FLT_DIG) "g", fvalue_get_floating(&finfo->value));
6621 			}
6622 			label_len = (int)strlen(display_label_str);
6623 			break;
6624 
6625 		case FT_DOUBLE:
6626 			if (hfinfo->display & BASE_UNIT_STRING) {
6627 				double d_value = fvalue_get_floating(&finfo->value);
6628 				g_snprintf(display_label_str, label_str_size,
6629 						"%." G_STRINGIFY(DBL_DIG) "g%s", d_value,
6630 						unit_name_string_get_double(d_value, (const unit_name_string*)hfinfo->strings));
6631 			} else {
6632 				g_snprintf(display_label_str, label_str_size,
6633 						"%." G_STRINGIFY(DBL_DIG) "g", fvalue_get_floating(&finfo->value));
6634 			}
6635 			label_len = (int)strlen(display_label_str);
6636 			break;
6637 
6638 		case FT_STRING:
6639 		case FT_STRINGZ:
6640 		case FT_UINT_STRING:
6641 		case FT_STRINGZPAD:
6642 		case FT_STRINGZTRUNC:
6643 			bytes = (guint8 *)fvalue_get(&finfo->value);
6644 			tmp_str = hfinfo_format_text(NULL, hfinfo, bytes);
6645 			label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
6646 			wmem_free(NULL, tmp_str);
6647 			break;
6648 
6649 		default:
6650 			/* First try ftype string representation */
6651 			tmp_str = fvalue_to_string_repr(NULL, &finfo->value, FTREPR_DISPLAY, hfinfo->display);
6652 			if (!tmp_str) {
6653 				/* Default to show as bytes */
6654 				bytes = (guint8 *)fvalue_get(&finfo->value);
6655 				tmp_str = bytes_to_str(NULL, bytes, fvalue_length(&finfo->value));
6656 			}
6657 			label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
6658 			wmem_free(NULL, tmp_str);
6659 			break;
6660 	}
6661 	return label_len;
6662 }
6663 
6664 /* -------------------------- */
6665 const gchar *
proto_custom_set(proto_tree * tree,GSList * field_ids,gint occurrence,gchar * result,gchar * expr,const int size)6666 proto_custom_set(proto_tree* tree, GSList *field_ids, gint occurrence,
6667 		 gchar *result, gchar *expr, const int size)
6668 {
6669 	guint32             number;
6670 	guint64             number64;
6671 	guint8             *bytes;
6672 
6673 	int                 len, prev_len, last, i, offset_r = 0, offset_e = 0, label_len;
6674 	GPtrArray          *finfos;
6675 	field_info         *finfo         = NULL;
6676 	header_field_info*  hfinfo;
6677 	const gchar        *abbrev        = NULL;
6678 
6679 	const char *hf_str_val;
6680 	char number_buf[48];
6681 	const char *number_out;
6682 	char *str;
6683 	int *field_idx;
6684 	int field_id;
6685 	int ii = 0;
6686 
6687 	ws_assert(field_ids != NULL);
6688 	while ((field_idx = (int *) g_slist_nth_data(field_ids, ii++))) {
6689 		field_id = *field_idx;
6690 		PROTO_REGISTRAR_GET_NTH((guint)field_id, hfinfo);
6691 
6692 		/* do we need to rewind ? */
6693 		if (!hfinfo)
6694 			return "";
6695 
6696 		if (occurrence < 0) {
6697 			/* Search other direction */
6698 			while (hfinfo->same_name_prev_id != -1) {
6699 				PROTO_REGISTRAR_GET_NTH(hfinfo->same_name_prev_id, hfinfo);
6700 			}
6701 		}
6702 
6703 		prev_len = 0; /* Reset handled occurrences */
6704 
6705 		while (hfinfo) {
6706 			finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
6707 
6708 			if (!finfos || !(len = g_ptr_array_len(finfos))) {
6709 				if (occurrence < 0) {
6710 					hfinfo = hfinfo->same_name_next;
6711 				} else {
6712 					hfinfo = hfinfo_same_name_get_prev(hfinfo);
6713 				}
6714 				continue;
6715 			}
6716 
6717 			/* Are there enough occurrences of the field? */
6718 			if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
6719 				if (occurrence < 0) {
6720 					hfinfo = hfinfo->same_name_next;
6721 				} else {
6722 					hfinfo = hfinfo_same_name_get_prev(hfinfo);
6723 				}
6724 				prev_len += len;
6725 				continue;
6726 			}
6727 
6728 			/* Calculate single index or set outer bounderies */
6729 			if (occurrence < 0) {
6730 				i = occurrence + len + prev_len;
6731 				last = i;
6732 			} else if (occurrence > 0) {
6733 				i = occurrence - 1 - prev_len;
6734 				last = i;
6735 			} else {
6736 				i = 0;
6737 				last = len - 1;
6738 			}
6739 
6740 			prev_len += len; /* Count handled occurrences */
6741 
6742 			while (i <= last) {
6743 				finfo = (field_info *)g_ptr_array_index(finfos, i);
6744 
6745 				if (offset_r && (offset_r < (size - 2)))
6746 					result[offset_r++] = ',';
6747 
6748 				if (offset_e && (offset_e < (size - 2)))
6749 					expr[offset_e++] = ',';
6750 
6751 				switch (hfinfo->type) {
6752 
6753 					case FT_NONE:
6754 					case FT_PROTOCOL:
6755 						/* Prevent multiple check marks */
6756 						if (strstr(result, UTF8_CHECK_MARK ",") == NULL) {
6757 							offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
6758 						} else {
6759 							result[--offset_r] = '\0'; /* Remove the added trailing ',' again */
6760 						}
6761 						break;
6762 
6763 					case FT_BOOLEAN:
6764 						offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
6765 
6766 						number64 = fvalue_get_uinteger64(&finfo->value);
6767 						offset_e += protoo_strlcpy(expr+offset_e,
6768 								number64 ? "1" : "0", size-offset_e);
6769 						break;
6770 
6771 					case FT_CHAR:
6772 						offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
6773 
6774 						number = fvalue_get_uinteger(&finfo->value);
6775 
6776 						if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display) == BASE_NONE) {
6777 							hf_str_val = hf_try_val_to_str(number, hfinfo);
6778 							g_snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
6779 						} else {
6780 							number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
6781 
6782 							(void) g_strlcpy(expr+offset_e, number_out, size-offset_e);
6783 						}
6784 
6785 						offset_e = (int)strlen(expr);
6786 						break;
6787 
6788 						/* XXX - make these just FT_NUMBER? */
6789 					case FT_INT8:
6790 					case FT_INT16:
6791 					case FT_INT24:
6792 					case FT_INT32:
6793 					case FT_UINT8:
6794 					case FT_UINT16:
6795 					case FT_UINT24:
6796 					case FT_UINT32:
6797 					case FT_FRAMENUM:
6798 						offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
6799 
6800 						hf_str_val = NULL;
6801 						number = IS_FT_INT(hfinfo->type) ?
6802 							(guint32) fvalue_get_sinteger(&finfo->value) :
6803 							fvalue_get_uinteger(&finfo->value);
6804 
6805 						if (hfinfo->strings && hfinfo->type != FT_FRAMENUM && FIELD_DISPLAY(hfinfo->display) != BASE_CUSTOM) {
6806 							hf_str_val = hf_try_val_to_str(number, hfinfo);
6807 						}
6808 
6809 						if (hf_str_val && FIELD_DISPLAY(hfinfo->display) == BASE_NONE) {
6810 
6811 							hf_str_val = hf_try_val_to_str(number, hfinfo);
6812 							g_snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
6813 						} else {
6814 							number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
6815 
6816 							(void) g_strlcpy(expr+offset_e, number_out, size-offset_e);
6817 						}
6818 
6819 						offset_e = (int)strlen(expr);
6820 						break;
6821 
6822 					case FT_INT40:
6823 					case FT_INT48:
6824 					case FT_INT56:
6825 					case FT_INT64:
6826 					case FT_UINT40:
6827 					case FT_UINT48:
6828 					case FT_UINT56:
6829 					case FT_UINT64:
6830 						offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
6831 
6832 						hf_str_val = NULL;
6833 						number64 = IS_FT_INT(hfinfo->type) ?
6834 							(guint64) fvalue_get_sinteger64(&finfo->value) :
6835 							fvalue_get_uinteger64(&finfo->value);
6836 
6837 						if (hfinfo->strings && hfinfo->type != FT_FRAMENUM && FIELD_DISPLAY(hfinfo->display) != BASE_CUSTOM) {
6838 							hf_str_val = hf_try_val64_to_str(number64, hfinfo);
6839 						}
6840 
6841 						if (hf_str_val && FIELD_DISPLAY(hfinfo->display) == BASE_NONE) {
6842 							g_snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
6843 						} else {
6844 							number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
6845 
6846 							(void) g_strlcpy(expr+offset_e, number_out, size-offset_e);
6847 						}
6848 
6849 						offset_e = (int)strlen(expr);
6850 						break;
6851 
6852 					case FT_REL_OID:
6853 						offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
6854 
6855 						bytes = (guint8 *)fvalue_get(&finfo->value);
6856 						str = rel_oid_encoded2string(NULL, bytes, fvalue_length(&finfo->value));
6857 						offset_e += protoo_strlcpy(expr+offset_e, str, size-offset_e);
6858 						wmem_free(NULL, str);
6859 						break;
6860 
6861 					case FT_OID:
6862 						offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
6863 
6864 						bytes = (guint8 *)fvalue_get(&finfo->value);
6865 						str = oid_encoded2string(NULL, bytes, fvalue_length(&finfo->value));
6866 						offset_e += protoo_strlcpy(expr+offset_e, str, size-offset_e);
6867 						wmem_free(NULL, str);
6868 						break;
6869 
6870 					case FT_SYSTEM_ID:
6871 						label_len = proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
6872 
6873 						offset_e += protoo_strlcpy(expr+offset_e, result+offset_r, size-offset_e);
6874 
6875 						offset_r += label_len;
6876 						break;
6877 
6878 					default:
6879 						offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
6880 						break;
6881 				}
6882 				i++;
6883 			}
6884 
6885 			switch (hfinfo->type) {
6886 
6887 				case FT_BOOLEAN:
6888 				case FT_CHAR:
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 				case FT_FRAMENUM:
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 				case FT_OID:
6907 				case FT_REL_OID:
6908 				case FT_SYSTEM_ID:
6909 					/* for these types, "expr" is filled in the loop above */
6910 					break;
6911 
6912 				default:
6913 					/* for all others, just copy "result" to "expr" */
6914 					(void) g_strlcpy(expr, result, size);
6915 					break;
6916 			}
6917 
6918 			if (!abbrev) {
6919 				/* Store abbrev for return value */
6920 				abbrev = hfinfo->abbrev;
6921 			}
6922 
6923 			if (occurrence == 0) {
6924 				/* Fetch next hfinfo with same name (abbrev) */
6925 				hfinfo = hfinfo_same_name_get_prev(hfinfo);
6926 			} else {
6927 				hfinfo = NULL;
6928 			}
6929 		}
6930 	}
6931 
6932 	return abbrev ? abbrev : "";
6933 }
6934 
6935 
6936 /* Set text of proto_item after having already been created. */
6937 void
proto_item_set_text(proto_item * pi,const char * format,...)6938 proto_item_set_text(proto_item *pi, const char *format, ...)
6939 {
6940 	field_info *fi = NULL;
6941 	va_list     ap;
6942 
6943 	TRY_TO_FAKE_THIS_REPR_VOID(pi);
6944 
6945 	fi = PITEM_FINFO(pi);
6946 	if (fi == NULL)
6947 		return;
6948 
6949 	if (fi->rep) {
6950 		ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep);
6951 		fi->rep = NULL;
6952 	}
6953 
6954 	va_start(ap, format);
6955 	proto_tree_set_representation(pi, format, ap);
6956 	va_end(ap);
6957 }
6958 
6959 /* Append to text of proto_item after having already been created. */
6960 void
proto_item_append_text(proto_item * pi,const char * format,...)6961 proto_item_append_text(proto_item *pi, const char *format, ...)
6962 {
6963 	field_info *fi = NULL;
6964 	size_t      curlen;
6965 	va_list     ap;
6966 
6967 	TRY_TO_FAKE_THIS_REPR_VOID(pi);
6968 
6969 	fi = PITEM_FINFO(pi);
6970 	if (fi == NULL) {
6971 		return;
6972 	}
6973 
6974 	if (!proto_item_is_hidden(pi)) {
6975 		/*
6976 		 * If we don't already have a representation,
6977 		 * generate the default representation.
6978 		 */
6979 		if (fi->rep == NULL) {
6980 			ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
6981 			proto_item_fill_label(fi, fi->rep->representation);
6982 		}
6983 
6984 		curlen = strlen(fi->rep->representation);
6985 		if (ITEM_LABEL_LENGTH > curlen) {
6986 			va_start(ap, format);
6987 			g_vsnprintf(fi->rep->representation + curlen,
6988 				ITEM_LABEL_LENGTH - (gulong) curlen, format, ap);
6989 			va_end(ap);
6990 		}
6991 	}
6992 }
6993 
6994 /* Prepend to text of proto_item after having already been created. */
6995 void
proto_item_prepend_text(proto_item * pi,const char * format,...)6996 proto_item_prepend_text(proto_item *pi, const char *format, ...)
6997 {
6998 	field_info *fi = NULL;
6999 	char        representation[ITEM_LABEL_LENGTH];
7000 	va_list     ap;
7001 
7002 	TRY_TO_FAKE_THIS_REPR_VOID(pi);
7003 
7004 	fi = PITEM_FINFO(pi);
7005 	if (fi == NULL) {
7006 		return;
7007 	}
7008 
7009 	if (!proto_item_is_hidden(pi)) {
7010 		/*
7011 		 * If we don't already have a representation,
7012 		 * generate the default representation.
7013 		 */
7014 		if (fi->rep == NULL) {
7015 			ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
7016 			proto_item_fill_label(fi, representation);
7017 		} else
7018 			(void) g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH);
7019 
7020 		va_start(ap, format);
7021 		g_vsnprintf(fi->rep->representation,
7022 			ITEM_LABEL_LENGTH, format, ap);
7023 		va_end(ap);
7024 		(void) g_strlcat(fi->rep->representation, representation, ITEM_LABEL_LENGTH);
7025 	}
7026 }
7027 
7028 static void
finfo_set_len(field_info * fi,const gint length)7029 finfo_set_len(field_info *fi, const gint length)
7030 {
7031 	gint length_remaining;
7032 
7033 	DISSECTOR_ASSERT_HINT(length >= 0, fi->hfinfo->abbrev);
7034 	length_remaining = tvb_captured_length_remaining(fi->ds_tvb, fi->start);
7035 	if (length > length_remaining)
7036 		fi->length = length_remaining;
7037 	else
7038 		fi->length = length;
7039 
7040 	/*
7041 	 * You cannot just make the "len" field of a GByteArray
7042 	 * larger, if there's no data to back that length;
7043 	 * you can only make it smaller.
7044 	 */
7045 	if (fi->value.ftype->ftype == FT_BYTES && fi->length <= (gint)fi->value.value.bytes->len)
7046 		fi->value.value.bytes->len = fi->length;
7047 }
7048 
7049 void
proto_item_set_len(proto_item * pi,const gint length)7050 proto_item_set_len(proto_item *pi, const gint length)
7051 {
7052 	field_info *fi;
7053 
7054 	TRY_TO_FAKE_THIS_REPR_VOID(pi);
7055 
7056 	fi = PITEM_FINFO(pi);
7057 	if (fi == NULL)
7058 		return;
7059 
7060 	finfo_set_len(fi, length);
7061 }
7062 
7063 /*
7064  * Sets the length of the item based on its start and on the specified
7065  * offset, which is the offset past the end of the item; as the start
7066  * in the item is relative to the beginning of the data source tvbuff,
7067  * we need to pass in a tvbuff - the end offset is relative to the beginning
7068  * of that tvbuff.
7069  */
7070 void
proto_item_set_end(proto_item * pi,tvbuff_t * tvb,gint end)7071 proto_item_set_end(proto_item *pi, tvbuff_t *tvb, gint end)
7072 {
7073 	field_info *fi;
7074 	gint length;
7075 
7076 	TRY_TO_FAKE_THIS_REPR_VOID(pi);
7077 
7078 	fi = PITEM_FINFO(pi);
7079 	if (fi == NULL)
7080 		return;
7081 
7082 	end += tvb_raw_offset(tvb);
7083 	DISSECTOR_ASSERT(end >= fi->start);
7084 	length = end - fi->start;
7085 
7086 	finfo_set_len(fi, length);
7087 }
7088 
7089 int
proto_item_get_len(const proto_item * pi)7090 proto_item_get_len(const proto_item *pi)
7091 {
7092 	field_info *fi;
7093 
7094 	if (!pi)
7095 		return -1;
7096 	fi = PITEM_FINFO(pi);
7097 	return fi ? fi->length : -1;
7098 }
7099 
7100 void
proto_item_set_bits_offset_len(proto_item * ti,int bits_offset,int bits_len)7101 proto_item_set_bits_offset_len(proto_item *ti, int bits_offset, int bits_len) {
7102 	if (!ti) {
7103 		return;
7104 	}
7105 	FI_SET_FLAG(PNODE_FINFO(ti), FI_BITS_OFFSET(bits_offset));
7106 	FI_SET_FLAG(PNODE_FINFO(ti), FI_BITS_SIZE(bits_len));
7107 }
7108 
7109 char *
proto_item_get_display_repr(wmem_allocator_t * scope,proto_item * pi)7110 proto_item_get_display_repr(wmem_allocator_t *scope, proto_item *pi)
7111 {
7112 	field_info *fi;
7113 
7114 	if (!pi)
7115 		return "";
7116 	fi = PITEM_FINFO(pi);
7117 	DISSECTOR_ASSERT(fi->hfinfo != NULL);
7118 	return fvalue_to_string_repr(scope, &fi->value, FTREPR_DISPLAY, fi->hfinfo->display);
7119 }
7120 
7121 proto_tree *
proto_tree_create_root(packet_info * pinfo)7122 proto_tree_create_root(packet_info *pinfo)
7123 {
7124 	proto_node *pnode;
7125 
7126 	/* Initialize the proto_node */
7127 	pnode = g_slice_new(proto_tree);
7128 	PROTO_NODE_INIT(pnode);
7129 	pnode->parent = NULL;
7130 	PNODE_FINFO(pnode) = NULL;
7131 	pnode->tree_data = g_slice_new(tree_data_t);
7132 
7133 	/* Make sure we can access pinfo everywhere */
7134 	pnode->tree_data->pinfo = pinfo;
7135 
7136 	/* Don't initialize the tree_data_t. Wait until we know we need it */
7137 	pnode->tree_data->interesting_hfids = NULL;
7138 
7139 	/* Set the default to FALSE so it's easier to
7140 	 * find errors; if we expect to see the protocol tree
7141 	 * but for some reason the default 'visible' is not
7142 	 * changed, then we'll find out very quickly. */
7143 	pnode->tree_data->visible = FALSE;
7144 
7145 	/* Make sure that we fake protocols (if possible) */
7146 	pnode->tree_data->fake_protocols = TRUE;
7147 
7148 	/* Keep track of the number of children */
7149 	pnode->tree_data->count = 0;
7150 
7151 	return (proto_tree *)pnode;
7152 }
7153 
7154 
7155 /* "prime" a proto_tree with a single hfid that a dfilter
7156  * is interested in. */
7157 void
proto_tree_prime_with_hfid(proto_tree * tree _U_,const gint hfid)7158 proto_tree_prime_with_hfid(proto_tree *tree _U_, const gint hfid)
7159 {
7160 	header_field_info *hfinfo;
7161 
7162 	PROTO_REGISTRAR_GET_NTH(hfid, hfinfo);
7163 	/* this field is referenced by a filter so increase the refcount.
7164 	   also increase the refcount for the parent, i.e the protocol.
7165 	*/
7166 	hfinfo->ref_type = HF_REF_TYPE_DIRECT;
7167 	/* only increase the refcount if there is a parent.
7168 	   if this is a protocol and not a field then parent will be -1
7169 	   and there is no parent to add any refcounting for.
7170 	*/
7171 	if (hfinfo->parent != -1) {
7172 		header_field_info *parent_hfinfo;
7173 		PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
7174 
7175 		/* Mark parent as indirectly referenced unless it is already directly
7176 		 * referenced, i.e. the user has specified the parent in a filter.
7177 		 */
7178 		if (parent_hfinfo->ref_type != HF_REF_TYPE_DIRECT)
7179 			parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
7180 	}
7181 }
7182 
7183 proto_tree *
proto_item_add_subtree(proto_item * pi,const gint idx)7184 proto_item_add_subtree(proto_item *pi,	const gint idx) {
7185 	field_info *fi;
7186 
7187 	if (!pi)
7188 		return NULL;
7189 
7190 	DISSECTOR_ASSERT(idx >= 0 && idx < num_tree_types);
7191 
7192 	fi = PITEM_FINFO(pi);
7193 	if (!fi)
7194 		return (proto_tree *)pi;
7195 
7196 	fi->tree_type = idx;
7197 
7198 	return (proto_tree *)pi;
7199 }
7200 
7201 proto_tree *
proto_item_get_subtree(proto_item * pi)7202 proto_item_get_subtree(proto_item *pi) {
7203 	field_info *fi;
7204 
7205 	if (!pi)
7206 		return NULL;
7207 	fi = PITEM_FINFO(pi);
7208 	if ( (!fi) || (fi->tree_type == -1) )
7209 		return NULL;
7210 	return (proto_tree *)pi;
7211 }
7212 
7213 proto_item *
proto_item_get_parent(const proto_item * ti)7214 proto_item_get_parent(const proto_item *ti) {
7215 	if (!ti)
7216 		return NULL;
7217 	return ti->parent;
7218 }
7219 
7220 proto_item *
proto_item_get_parent_nth(proto_item * ti,int gen)7221 proto_item_get_parent_nth(proto_item *ti, int gen) {
7222 	if (!ti)
7223 		return NULL;
7224 	while (gen--) {
7225 		ti = ti->parent;
7226 		if (!ti)
7227 			return NULL;
7228 	}
7229 	return ti;
7230 }
7231 
7232 
7233 proto_item *
proto_tree_get_parent(proto_tree * tree)7234 proto_tree_get_parent(proto_tree *tree) {
7235 	if (!tree)
7236 		return NULL;
7237 	return (proto_item *)tree;
7238 }
7239 
7240 proto_tree *
proto_tree_get_parent_tree(proto_tree * tree)7241 proto_tree_get_parent_tree(proto_tree *tree) {
7242 	if (!tree)
7243 		return NULL;
7244 
7245 	/* we're the root tree, there's no parent
7246 	   return ourselves so the caller has at least a tree to attach to */
7247 	if (!tree->parent)
7248 		return tree;
7249 
7250 	return (proto_tree *)tree->parent;
7251 }
7252 
7253 proto_tree *
proto_tree_get_root(proto_tree * tree)7254 proto_tree_get_root(proto_tree *tree) {
7255 	if (!tree)
7256 		return NULL;
7257 	while (tree->parent) {
7258 		tree = tree->parent;
7259 	}
7260 	return tree;
7261 }
7262 
7263 void
proto_tree_move_item(proto_tree * tree,proto_item * fixed_item,proto_item * item_to_move)7264 proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
7265 		     proto_item *item_to_move)
7266 {
7267 	/* This function doesn't generate any values. It only reorganizes the prococol tree
7268 	 * so we can bail out immediately if it isn't visible. */
7269 	if (!tree || !PTREE_DATA(tree)->visible)
7270 		return;
7271 
7272 	DISSECTOR_ASSERT(item_to_move->parent == tree);
7273 	DISSECTOR_ASSERT(fixed_item->parent == tree);
7274 
7275 	/*** cut item_to_move out ***/
7276 
7277 	/* is item_to_move the first? */
7278 	if (tree->first_child == item_to_move) {
7279 		/* simply change first child to next */
7280 		tree->first_child = item_to_move->next;
7281 
7282 		DISSECTOR_ASSERT(tree->last_child != item_to_move);
7283 	} else {
7284 		proto_item *curr_item;
7285 		/* find previous and change it's next */
7286 		for (curr_item = tree->first_child; curr_item != NULL; curr_item = curr_item->next) {
7287 			if (curr_item->next == item_to_move) {
7288 				break;
7289 			}
7290 		}
7291 
7292 		DISSECTOR_ASSERT(curr_item);
7293 
7294 		curr_item->next = item_to_move->next;
7295 
7296 		/* fix last_child if required */
7297 		if (tree->last_child == item_to_move) {
7298 			tree->last_child = curr_item;
7299 		}
7300 	}
7301 
7302 	/*** insert to_move after fixed ***/
7303 	item_to_move->next = fixed_item->next;
7304 	fixed_item->next = item_to_move;
7305 	if (tree->last_child == fixed_item) {
7306 		tree->last_child = item_to_move;
7307 	}
7308 }
7309 
7310 void
proto_tree_set_appendix(proto_tree * tree,tvbuff_t * tvb,gint start,const gint length)7311 proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, gint start,
7312 			const gint length)
7313 {
7314 	field_info *fi;
7315 
7316 	if (tree == NULL)
7317 		return;
7318 
7319 	fi = PTREE_FINFO(tree);
7320 	if (fi == NULL)
7321 		return;
7322 
7323 	start += tvb_raw_offset(tvb);
7324 	DISSECTOR_ASSERT(start >= 0);
7325 	DISSECTOR_ASSERT(length >= 0);
7326 
7327 	fi->appendix_start = start;
7328 	fi->appendix_length = length;
7329 }
7330 
7331 static void
check_valid_filter_name_or_fail(const char * filter_name)7332 check_valid_filter_name_or_fail(const char *filter_name)
7333 {
7334 	gboolean found_invalid = proto_check_field_name(filter_name);
7335 
7336 	/* Additionally forbid upper case characters. */
7337 	if (!found_invalid) {
7338 		for (guint i = 0; filter_name[i]; i++) {
7339 			if (g_ascii_isupper(filter_name[i])) {
7340 				found_invalid = TRUE;
7341 				break;
7342 			}
7343 		}
7344 	}
7345 
7346 	if (found_invalid) {
7347 		ws_error("Protocol filter name \"%s\" has one or more invalid characters."
7348 			" Allowed are lower characters, digits, '-', '_' and non-repeating '.'."
7349 			" This might be caused by an inappropriate plugin or a development error.", filter_name);
7350 	}
7351 
7352 	const char *reserved_filter_names[] = {
7353 		/* Display filter keywords. */
7354 		"eq",
7355 		"ne",
7356 		"gt",
7357 		"ge",
7358 		"lt",
7359 		"le",
7360 		"bitwise_and",
7361 		"contains",
7362 		"matches",
7363 		"not",
7364 		"and",
7365 		"or",
7366 		"in",
7367 		NULL
7368 	};
7369 
7370 	/* Check for reserved keywords. */
7371 	for (const char **ptr = reserved_filter_names; *ptr != NULL; ptr++) {
7372 		if (strcmp(*ptr, filter_name) == 0) {
7373 			ws_error("Protocol filter name \"%s\" is a reserved keyword.", filter_name);
7374 		}
7375 	}
7376 }
7377 
7378 int
proto_register_protocol(const char * name,const char * short_name,const char * filter_name)7379 proto_register_protocol(const char *name, const char *short_name,
7380 			const char *filter_name)
7381 {
7382 	protocol_t *protocol;
7383 	header_field_info *hfinfo;
7384 
7385 	/*
7386 	 * Make sure there's not already a protocol with any of those
7387 	 * names.  Crash if there is, as that's an error in the code
7388 	 * or an inappropriate plugin.
7389 	 * This situation has to be fixed to not register more than one
7390 	 * protocol with the same name.
7391 	 */
7392 
7393 	if (g_hash_table_lookup(proto_names, name)) {
7394 		/* ws_error will terminate the program */
7395 		ws_error("Duplicate protocol name \"%s\"!"
7396 			" This might be caused by an inappropriate plugin or a development error.", name);
7397 	}
7398 
7399 	if (g_hash_table_lookup(proto_short_names, short_name)) {
7400 		ws_error("Duplicate protocol short_name \"%s\"!"
7401 			" This might be caused by an inappropriate plugin or a development error.", short_name);
7402 	}
7403 
7404 	check_valid_filter_name_or_fail(filter_name);
7405 
7406 	if (g_hash_table_lookup(proto_filter_names, filter_name)) {
7407 		ws_error("Duplicate protocol filter_name \"%s\"!"
7408 			" This might be caused by an inappropriate plugin or a development error.", filter_name);
7409 	}
7410 
7411 	/*
7412 	 * Add this protocol to the list of known protocols;
7413 	 * the list is sorted by protocol short name.
7414 	 */
7415 	protocol = g_new(protocol_t, 1);
7416 	protocol->name = name;
7417 	protocol->short_name = short_name;
7418 	protocol->filter_name = filter_name;
7419 	protocol->fields = NULL; /* Delegate until actually needed */
7420 	protocol->is_enabled = TRUE; /* protocol is enabled by default */
7421 	protocol->enabled_by_default = TRUE; /* see previous comment */
7422 	protocol->can_toggle = TRUE;
7423 	protocol->parent_proto_id = -1;
7424 	protocol->heur_list = NULL;
7425 
7426 	/* List will be sorted later by name, when all protocols completed registering */
7427 	protocols = g_list_prepend(protocols, protocol);
7428 	g_hash_table_insert(proto_names, (gpointer)name, protocol);
7429 	g_hash_table_insert(proto_filter_names, (gpointer)filter_name, protocol);
7430 	g_hash_table_insert(proto_short_names, (gpointer)short_name, protocol);
7431 
7432 	/* Here we allocate a new header_field_info struct */
7433 	hfinfo = g_slice_new(header_field_info);
7434 	hfinfo->name = name;
7435 	hfinfo->abbrev = filter_name;
7436 	hfinfo->type = FT_PROTOCOL;
7437 	hfinfo->display = BASE_NONE;
7438 	hfinfo->strings = protocol;
7439 	hfinfo->bitmask = 0;
7440 	hfinfo->ref_type = HF_REF_TYPE_NONE;
7441 	hfinfo->blurb = NULL;
7442 	hfinfo->parent = -1; /* This field differentiates protos and fields */
7443 
7444 	protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
7445 	return protocol->proto_id;
7446 }
7447 
7448 int
proto_register_protocol_in_name_only(const char * name,const char * short_name,const char * filter_name,int parent_proto,enum ftenum field_type)7449 proto_register_protocol_in_name_only(const char *name, const char *short_name, const char *filter_name, int parent_proto, enum ftenum field_type)
7450 {
7451 	protocol_t *protocol;
7452 	header_field_info *hfinfo;
7453 
7454 	/*
7455 	 * Helper protocols don't need the strict rules as a "regular" protocol
7456 	 * Just register it in a list and make a hf_ field from it
7457 	 */
7458 	if ((field_type != FT_PROTOCOL) && (field_type != FT_BYTES)) {
7459 		ws_error("Pino \"%s\" must be of type FT_PROTOCOL or FT_BYTES.", name);
7460 	}
7461 
7462 	if (parent_proto < 0) {
7463 		ws_error("Must have a valid parent protocol for helper protocol \"%s\"!"
7464 			" This might be caused by an inappropriate plugin or a development error.", name);
7465 	}
7466 
7467 	check_valid_filter_name_or_fail(filter_name);
7468 
7469 	/* Add this protocol to the list of helper protocols (just so it can be properly freed) */
7470 	protocol = g_new(protocol_t, 1);
7471 	protocol->name = name;
7472 	protocol->short_name = short_name;
7473 	protocol->filter_name = filter_name;
7474 	protocol->fields = NULL; /* Delegate until actually needed */
7475 
7476 	/* Enabling and toggling is really determined by parent protocol,
7477 	   but provide default values here */
7478 	protocol->is_enabled = TRUE;
7479 	protocol->enabled_by_default = TRUE;
7480 	protocol->can_toggle = TRUE;
7481 
7482 	protocol->parent_proto_id = parent_proto;
7483 	protocol->heur_list = NULL;
7484 
7485 	/* List will be sorted later by name, when all protocols completed registering */
7486 	protocols = g_list_prepend(protocols, protocol);
7487 
7488 	/* Here we allocate a new header_field_info struct */
7489 	hfinfo = g_slice_new(header_field_info);
7490 	hfinfo->name = name;
7491 	hfinfo->abbrev = filter_name;
7492 	hfinfo->type = field_type;
7493 	hfinfo->display = BASE_NONE;
7494 	if (field_type == FT_BYTES) {
7495 		hfinfo->display |= (BASE_NO_DISPLAY_VALUE|BASE_PROTOCOL_INFO);
7496 	}
7497 	hfinfo->strings = protocol;
7498 	hfinfo->bitmask = 0;
7499 	hfinfo->ref_type = HF_REF_TYPE_NONE;
7500 	hfinfo->blurb = NULL;
7501 	hfinfo->parent = -1; /* This field differentiates protos and fields */
7502 
7503 	protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
7504 	return protocol->proto_id;
7505 }
7506 
7507 gboolean
proto_deregister_protocol(const char * short_name)7508 proto_deregister_protocol(const char *short_name)
7509 {
7510 	protocol_t *protocol;
7511 	header_field_info *hfinfo;
7512 	int proto_id;
7513 	guint i;
7514 
7515 	proto_id = proto_get_id_by_short_name(short_name);
7516 	protocol = find_protocol_by_id(proto_id);
7517 	if (protocol == NULL)
7518 		return FALSE;
7519 
7520 	g_hash_table_remove(proto_names, protocol->name);
7521 	g_hash_table_remove(proto_short_names, (gpointer)short_name);
7522 	g_hash_table_remove(proto_filter_names, (gpointer)protocol->filter_name);
7523 
7524 	if (protocol->fields) {
7525 		for (i = 0; i < protocol->fields->len; i++) {
7526 			hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i);
7527 			hfinfo_remove_from_gpa_name_map(hfinfo);
7528 			expert_deregister_expertinfo(hfinfo->abbrev);
7529 			g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
7530 		}
7531 		g_ptr_array_free(protocol->fields, TRUE);
7532 		protocol->fields = NULL;
7533 	}
7534 
7535 	g_list_free(protocol->heur_list);
7536 
7537 	/* Remove this protocol from the list of known protocols */
7538 	protocols = g_list_remove(protocols, protocol);
7539 
7540 	g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
7541 	g_hash_table_steal(gpa_name_map, protocol->filter_name);
7542 
7543 	g_free(last_field_name);
7544 	last_field_name = NULL;
7545 
7546 	return TRUE;
7547 }
7548 
7549 void
proto_register_alias(const int proto_id,const char * alias_name)7550 proto_register_alias(const int proto_id, const char *alias_name)
7551 {
7552 	protocol_t *protocol;
7553 
7554 	protocol = find_protocol_by_id(proto_id);
7555 	if (alias_name && protocol) {
7556 		g_hash_table_insert(gpa_protocol_aliases, (gpointer) alias_name, (gpointer)protocol->filter_name);
7557 	}
7558 }
7559 
7560 /*
7561  * Routines to use to iterate over the protocols.
7562  * The argument passed to the iterator routines is an opaque cookie to
7563  * their callers; it's the GList pointer for the current element in
7564  * the list.
7565  * The ID of the protocol is returned, or -1 if there is no protocol.
7566  */
7567 int
proto_get_first_protocol(void ** cookie)7568 proto_get_first_protocol(void **cookie)
7569 {
7570 	protocol_t *protocol;
7571 
7572 	if (protocols == NULL)
7573 		return -1;
7574 	*cookie = protocols;
7575 	protocol = (protocol_t *)protocols->data;
7576 	return protocol->proto_id;
7577 }
7578 
7579 int
proto_get_data_protocol(void * cookie)7580 proto_get_data_protocol(void *cookie)
7581 {
7582 	GList *list_item = (GList *)cookie;
7583 
7584 	protocol_t *protocol = (protocol_t *)list_item->data;
7585 	return protocol->proto_id;
7586 }
7587 
7588 int
proto_get_next_protocol(void ** cookie)7589 proto_get_next_protocol(void **cookie)
7590 {
7591 	GList      *list_item = (GList *)*cookie;
7592 	protocol_t *protocol;
7593 
7594 	list_item = g_list_next(list_item);
7595 	if (list_item == NULL)
7596 		return -1;
7597 	*cookie = list_item;
7598 	protocol = (protocol_t *)list_item->data;
7599 	return protocol->proto_id;
7600 }
7601 
7602 /* XXX: Unfortunately certain functions in proto_hier_tree_model.c
7603         assume that the cookie stored by
7604         proto_get_(first|next)_protocol_field() will never have a
7605         value of NULL. So, to preserve this semantic, the cookie value
7606         below is adjusted so that the cookie value stored is 1 + the
7607         current (zero-based) array index.
7608 */
7609 header_field_info *
proto_get_first_protocol_field(const int proto_id,void ** cookie)7610 proto_get_first_protocol_field(const int proto_id, void **cookie)
7611 {
7612 	protocol_t *protocol = find_protocol_by_id(proto_id);
7613 
7614 	if ((protocol == NULL) || (protocol->fields == NULL) || (protocol->fields->len == 0))
7615 		return NULL;
7616 
7617 	*cookie = GUINT_TO_POINTER(0 + 1);
7618 	return (header_field_info *)g_ptr_array_index(protocol->fields, 0);
7619 }
7620 
7621 header_field_info *
proto_get_next_protocol_field(const int proto_id,void ** cookie)7622 proto_get_next_protocol_field(const int proto_id, void **cookie)
7623 {
7624 	protocol_t *protocol = find_protocol_by_id(proto_id);
7625 	guint       i        = GPOINTER_TO_UINT(*cookie) - 1;
7626 
7627 	i++;
7628 
7629 	if ((protocol->fields == NULL) || (i >= protocol->fields->len))
7630 		return NULL;
7631 
7632 	*cookie = GUINT_TO_POINTER(i + 1);
7633 	return (header_field_info *)g_ptr_array_index(protocol->fields, i);
7634 }
7635 
7636 protocol_t *
find_protocol_by_id(const int proto_id)7637 find_protocol_by_id(const int proto_id)
7638 {
7639 	header_field_info *hfinfo;
7640 
7641 	if (proto_id < 0)
7642 		return NULL;
7643 
7644 	PROTO_REGISTRAR_GET_NTH(proto_id, hfinfo);
7645 	if (hfinfo->type != FT_PROTOCOL) {
7646 		DISSECTOR_ASSERT(hfinfo->display & BASE_PROTOCOL_INFO);
7647 	}
7648 	return (protocol_t *)hfinfo->strings;
7649 }
7650 
7651 int
proto_get_id(const protocol_t * protocol)7652 proto_get_id(const protocol_t *protocol)
7653 {
7654 	return protocol->proto_id;
7655 }
7656 
7657 gboolean
proto_name_already_registered(const gchar * name)7658 proto_name_already_registered(const gchar *name)
7659 {
7660 	DISSECTOR_ASSERT_HINT(name, "No name present");
7661 
7662 	if (g_hash_table_lookup(proto_names, name) != NULL)
7663 		return TRUE;
7664 	return FALSE;
7665 }
7666 
7667 int
proto_get_id_by_filter_name(const gchar * filter_name)7668 proto_get_id_by_filter_name(const gchar *filter_name)
7669 {
7670 	const protocol_t *protocol = NULL;
7671 
7672 	DISSECTOR_ASSERT_HINT(filter_name, "No filter name present");
7673 
7674 	protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
7675 
7676 	if (protocol == NULL)
7677 		return -1;
7678 	return protocol->proto_id;
7679 }
7680 
7681 int
proto_get_id_by_short_name(const gchar * short_name)7682 proto_get_id_by_short_name(const gchar *short_name)
7683 {
7684 	const protocol_t *protocol = NULL;
7685 
7686 	DISSECTOR_ASSERT_HINT(short_name, "No short name present");
7687 
7688 	protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
7689 
7690 	if (protocol == NULL)
7691 		return -1;
7692 	return protocol->proto_id;
7693 }
7694 
7695 const char *
proto_get_protocol_name(const int proto_id)7696 proto_get_protocol_name(const int proto_id)
7697 {
7698 	protocol_t *protocol;
7699 
7700 	protocol = find_protocol_by_id(proto_id);
7701 
7702 	if (protocol == NULL)
7703 		return NULL;
7704 	return protocol->name;
7705 }
7706 
7707 const char *
proto_get_protocol_short_name(const protocol_t * protocol)7708 proto_get_protocol_short_name(const protocol_t *protocol)
7709 {
7710 	if (protocol == NULL)
7711 		return "(none)";
7712 	return protocol->short_name;
7713 }
7714 
7715 const char *
proto_get_protocol_long_name(const protocol_t * protocol)7716 proto_get_protocol_long_name(const protocol_t *protocol)
7717 {
7718 	if (protocol == NULL)
7719 		return "(none)";
7720 	return protocol->name;
7721 }
7722 
7723 const char *
proto_get_protocol_filter_name(const int proto_id)7724 proto_get_protocol_filter_name(const int proto_id)
7725 {
7726 	protocol_t *protocol;
7727 
7728 	protocol = find_protocol_by_id(proto_id);
7729 	if (protocol == NULL)
7730 		return "(none)";
7731 	return protocol->filter_name;
7732 }
7733 
proto_add_heuristic_dissector(protocol_t * protocol,const char * short_name)7734 void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
7735 {
7736 	heur_dtbl_entry_t* heuristic_dissector;
7737 
7738 	if (protocol == NULL)
7739 		return;
7740 
7741 	heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
7742 	if (heuristic_dissector != NULL)
7743 	{
7744 		protocol->heur_list = g_list_prepend (protocol->heur_list, heuristic_dissector);
7745 	}
7746 }
7747 
proto_heuristic_dissector_foreach(const protocol_t * protocol,GFunc func,gpointer user_data)7748 void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, gpointer user_data)
7749 {
7750 	if (protocol == NULL)
7751 		return;
7752 
7753 	g_list_foreach(protocol->heur_list, func, user_data);
7754 }
7755 
7756 void
proto_get_frame_protocols(const wmem_list_t * layers,gboolean * is_ip,gboolean * is_tcp,gboolean * is_udp,gboolean * is_sctp,gboolean * is_tls,gboolean * is_rtp,gboolean * is_lte_rlc)7757 proto_get_frame_protocols(const wmem_list_t *layers, gboolean *is_ip,
7758 			  gboolean *is_tcp, gboolean *is_udp,
7759 			  gboolean *is_sctp, gboolean *is_tls,
7760 			  gboolean *is_rtp,
7761 			  gboolean *is_lte_rlc)
7762 {
7763 	wmem_list_frame_t *protos = wmem_list_head(layers);
7764 	int	    proto_id;
7765 	const char *proto_name;
7766 
7767 	/* Walk the list of a available protocols in the packet and
7768 	   attempt to find "major" ones. */
7769 	/* It might make more sense to assemble and return a bitfield. */
7770 	while (protos != NULL)
7771 	{
7772 		proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos));
7773 		proto_name = proto_get_protocol_filter_name(proto_id);
7774 
7775 		if (is_ip && ((!strcmp(proto_name, "ip")) ||
7776 			      (!strcmp(proto_name, "ipv6")))) {
7777 			*is_ip = TRUE;
7778 		} else if (is_tcp && !strcmp(proto_name, "tcp")) {
7779 			*is_tcp = TRUE;
7780 		} else if (is_udp && !strcmp(proto_name, "udp")) {
7781 			*is_udp = TRUE;
7782 		} else if (is_sctp && !strcmp(proto_name, "sctp")) {
7783 			*is_sctp = TRUE;
7784 		} else if (is_tls && !strcmp(proto_name, "tls")) {
7785 			*is_tls = TRUE;
7786 		} else if (is_rtp && !strcmp(proto_name, "rtp")) {
7787 			*is_rtp = TRUE;
7788 		} else if (is_lte_rlc && !strcmp(proto_name, "rlc-lte")) {
7789 			*is_lte_rlc = TRUE;
7790 		}
7791 
7792 		protos = wmem_list_frame_next(protos);
7793 	}
7794 }
7795 
7796 gboolean
proto_is_frame_protocol(const wmem_list_t * layers,const char * proto_name)7797 proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
7798 {
7799 	wmem_list_frame_t *protos = wmem_list_head(layers);
7800 	int	    proto_id;
7801 	const char *name;
7802 
7803 	/* Walk the list of a available protocols in the packet and
7804 	   attempt to find the specified protocol. */
7805 	while (protos != NULL)
7806 	{
7807 		proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos));
7808 		name = proto_get_protocol_filter_name(proto_id);
7809 
7810 		if (!strcmp(name, proto_name))
7811 		{
7812 			return TRUE;
7813 		}
7814 
7815 		protos = wmem_list_frame_next(protos);
7816 	}
7817 
7818 	return FALSE;
7819 }
7820 
7821 gboolean
proto_is_pino(const protocol_t * protocol)7822 proto_is_pino(const protocol_t *protocol)
7823 {
7824 	return (protocol->parent_proto_id != -1);
7825 }
7826 
7827 gboolean
proto_is_protocol_enabled(const protocol_t * protocol)7828 proto_is_protocol_enabled(const protocol_t *protocol)
7829 {
7830 	if (protocol == NULL)
7831 		return FALSE;
7832 
7833 	//parent protocol determines enable/disable for helper dissectors
7834 	if (proto_is_pino(protocol))
7835 		return proto_is_protocol_enabled(find_protocol_by_id(protocol->parent_proto_id));
7836 
7837 	return protocol->is_enabled;
7838 }
7839 
7840 gboolean
proto_is_protocol_enabled_by_default(const protocol_t * protocol)7841 proto_is_protocol_enabled_by_default(const protocol_t *protocol)
7842 {
7843 	//parent protocol determines enable/disable for helper dissectors
7844 	if (proto_is_pino(protocol))
7845 		return proto_is_protocol_enabled_by_default(find_protocol_by_id(protocol->parent_proto_id));
7846 
7847 	return protocol->enabled_by_default;
7848 }
7849 
7850 gboolean
proto_can_toggle_protocol(const int proto_id)7851 proto_can_toggle_protocol(const int proto_id)
7852 {
7853 	protocol_t *protocol;
7854 
7855 	protocol = find_protocol_by_id(proto_id);
7856 	//parent protocol determines toggling for helper dissectors
7857 	if (proto_is_pino(protocol))
7858 		return proto_can_toggle_protocol(protocol->parent_proto_id);
7859 
7860 	return protocol->can_toggle;
7861 }
7862 
7863 void
proto_disable_by_default(const int proto_id)7864 proto_disable_by_default(const int proto_id)
7865 {
7866 	protocol_t *protocol;
7867 
7868 	protocol = find_protocol_by_id(proto_id);
7869 	DISSECTOR_ASSERT(protocol->can_toggle);
7870 	DISSECTOR_ASSERT(proto_is_pino(protocol) == FALSE);
7871 	protocol->is_enabled = FALSE;
7872 	protocol->enabled_by_default = FALSE;
7873 }
7874 
7875 void
proto_set_decoding(const int proto_id,const gboolean enabled)7876 proto_set_decoding(const int proto_id, const gboolean enabled)
7877 {
7878 	protocol_t *protocol;
7879 
7880 	protocol = find_protocol_by_id(proto_id);
7881 	DISSECTOR_ASSERT(protocol->can_toggle);
7882 	DISSECTOR_ASSERT(proto_is_pino(protocol) == FALSE);
7883 	protocol->is_enabled = enabled;
7884 }
7885 
7886 void
proto_reenable_all(void)7887 proto_reenable_all(void)
7888 {
7889 	protocol_t *protocol;
7890 	GList      *list_item = protocols;
7891 
7892 	if (protocols == NULL)
7893 		return;
7894 
7895 	while (list_item) {
7896 		protocol = (protocol_t *)list_item->data;
7897 		if (protocol->can_toggle && protocol->enabled_by_default)
7898 			protocol->is_enabled = TRUE;
7899 		list_item = g_list_next(list_item);
7900 	}
7901 }
7902 
7903 void
proto_set_cant_toggle(const int proto_id)7904 proto_set_cant_toggle(const int proto_id)
7905 {
7906 	protocol_t *protocol;
7907 
7908 	protocol = find_protocol_by_id(proto_id);
7909 	protocol->can_toggle = FALSE;
7910 }
7911 
7912 static int
proto_register_field_common(protocol_t * proto,header_field_info * hfi,const int parent)7913 proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
7914 {
7915 	if (proto != NULL) {
7916 		g_ptr_array_add(proto->fields, hfi);
7917 	}
7918 
7919 	return proto_register_field_init(hfi, parent);
7920 }
7921 
7922 /* for use with static arrays only, since we don't allocate our own copies
7923 of the header_field_info struct contained within the hf_register_info struct */
7924 void
proto_register_field_array(const int parent,hf_register_info * hf,const int num_records)7925 proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
7926 {
7927 	hf_register_info *ptr = hf;
7928 	protocol_t	 *proto;
7929 	int		  i;
7930 
7931 	proto = find_protocol_by_id(parent);
7932 
7933 	if (proto->fields == NULL) {
7934 		proto->fields = g_ptr_array_sized_new(num_records);
7935 	}
7936 
7937 	for (i = 0; i < num_records; i++, ptr++) {
7938 		/*
7939 		 * Make sure we haven't registered this yet.
7940 		 * Most fields have variables associated with them
7941 		 * that are initialized to -1; some have array elements,
7942 		 * or possibly uninitialized variables, so we also allow
7943 		 * 0 (which is unlikely to be the field ID we get back
7944 		 * from "proto_register_field_init()").
7945 		 */
7946 		if (*ptr->p_id != -1 && *ptr->p_id != 0) {
7947 			fprintf(stderr,
7948 				"Duplicate field detected in call to proto_register_field_array: %s is already registered\n",
7949 				ptr->hfinfo.abbrev);
7950 			return;
7951 		}
7952 
7953 		*ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
7954 	}
7955 }
7956 
7957 void
proto_register_fields_section(const int parent,header_field_info * hfi,const int num_records)7958 proto_register_fields_section(const int parent, header_field_info *hfi, const int num_records)
7959 {
7960 	int		  i;
7961 	protocol_t	 *proto;
7962 
7963 	proto = find_protocol_by_id(parent);
7964 
7965 	if (proto->fields == NULL) {
7966 		proto->fields = g_ptr_array_sized_new(num_records);
7967 	}
7968 
7969 	for (i = 0; i < num_records; i++) {
7970 		/*
7971 		 * Make sure we haven't registered this yet.
7972 		 */
7973 		if (hfi[i].id != -1) {
7974 			fprintf(stderr,
7975 				"Duplicate field detected in call to proto_register_fields: %s is already registered\n",
7976 				hfi[i].abbrev);
7977 			return;
7978 		}
7979 
7980 		proto_register_field_common(proto, &hfi[i], parent);
7981 	}
7982 }
7983 
7984 void
proto_register_fields_manual(const int parent,header_field_info ** hfi,const int num_records)7985 proto_register_fields_manual(const int parent, header_field_info **hfi, const int num_records)
7986 {
7987 	int		  i;
7988 	protocol_t	 *proto;
7989 
7990 	proto = find_protocol_by_id(parent);
7991 
7992 	if (proto->fields == NULL) {
7993 		proto->fields = g_ptr_array_sized_new(num_records);
7994 	}
7995 
7996 
7997 	for (i = 0; i < num_records; i++) {
7998 		/*
7999 		 * Make sure we haven't registered this yet.
8000 		 */
8001 		if (hfi[i]->id != -1) {
8002 			fprintf(stderr,
8003 				"Duplicate field detected in call to proto_register_fields: %s is already registered\n",
8004 				hfi[i]->abbrev);
8005 			return;
8006 		}
8007 
8008 		proto_register_field_common(proto, hfi[i], parent);
8009 	}
8010 }
8011 
8012 /* deregister already registered fields */
8013 void
proto_deregister_field(const int parent,gint hf_id)8014 proto_deregister_field (const int parent, gint hf_id)
8015 {
8016 	header_field_info *hfi;
8017 	protocol_t       *proto;
8018 	guint             i;
8019 
8020 	g_free(last_field_name);
8021 	last_field_name = NULL;
8022 
8023 	if (hf_id == -1 || hf_id == 0)
8024 		return;
8025 
8026 	proto = find_protocol_by_id (parent);
8027 	if (!proto || proto->fields == NULL) {
8028 		return;
8029 	}
8030 
8031 	for (i = 0; i < proto->fields->len; i++) {
8032 		hfi = (header_field_info *)g_ptr_array_index(proto->fields, i);
8033 		if (hfi->id == hf_id) {
8034 			/* Found the hf_id in this protocol */
8035 			g_hash_table_steal(gpa_name_map, hfi->abbrev);
8036 			g_ptr_array_remove_index_fast(proto->fields, i);
8037 			g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
8038 			return;
8039 		}
8040 	}
8041 }
8042 
8043 void
proto_add_deregistered_data(void * data)8044 proto_add_deregistered_data (void *data)
8045 {
8046 	g_ptr_array_add(deregistered_data, data);
8047 }
8048 
8049 void
proto_add_deregistered_slice(gsize block_size,gpointer mem_block)8050 proto_add_deregistered_slice (gsize block_size, gpointer mem_block)
8051 {
8052 	struct g_slice_data *slice_data = g_slice_new(struct g_slice_data);
8053 
8054 	slice_data->block_size = block_size;
8055 	slice_data->mem_block = mem_block;
8056 
8057 	g_ptr_array_add(deregistered_slice, slice_data);
8058 }
8059 
proto_free_field_strings(ftenum_t field_type,unsigned int field_display,const void * field_strings)8060 void proto_free_field_strings (ftenum_t field_type, unsigned int field_display, const void *field_strings)
8061 {
8062 	if (field_strings == NULL) {
8063 		return;
8064 	}
8065 
8066 	switch (field_type) {
8067 		case FT_FRAMENUM:
8068 			/* This is just an integer represented as a pointer */
8069 			break;
8070 		case FT_PROTOCOL: {
8071 			protocol_t *protocol = (protocol_t *)field_strings;
8072 			g_free((gchar *)protocol->short_name);
8073 			break;
8074 		}
8075 		case FT_BOOLEAN: {
8076 			true_false_string *tf = (true_false_string *)field_strings;
8077 			g_free((gchar *)tf->true_string);
8078 			g_free((gchar *)tf->false_string);
8079 			break;
8080 		}
8081 		case FT_UINT40:
8082 		case FT_INT40:
8083 		case FT_UINT48:
8084 		case FT_INT48:
8085 		case FT_UINT56:
8086 		case FT_INT56:
8087 		case FT_UINT64:
8088 		case FT_INT64: {
8089 			/*
8090 			 * XXX - if it's BASE_RANGE_STRING, or
8091 			 * BASE_EXT_STRING, should we free it?
8092 			 */
8093 			if (field_display & BASE_UNIT_STRING) {
8094 				unit_name_string *unit = (unit_name_string *)field_strings;
8095 				g_free((gchar *)unit->singular);
8096 				g_free((gchar *)unit->plural);
8097 			} else {
8098 				val64_string *vs64 = (val64_string *)field_strings;
8099 				while (vs64->strptr) {
8100 					g_free((gchar *)vs64->strptr);
8101 					vs64++;
8102 				}
8103 			}
8104 			break;
8105 		}
8106 		case FT_CHAR:
8107 		case FT_UINT8:
8108 		case FT_INT8:
8109 		case FT_UINT16:
8110 		case FT_INT16:
8111 		case FT_UINT24:
8112 		case FT_INT24:
8113 		case FT_UINT32:
8114 		case FT_INT32:
8115 		case FT_FLOAT:
8116 		case FT_DOUBLE: {
8117 			/*
8118 			 * XXX - if it's BASE_RANGE_STRING, or
8119 			 * BASE_EXT_STRING, should we free it?
8120 			 */
8121 			if (field_display & BASE_UNIT_STRING) {
8122 				unit_name_string *unit = (unit_name_string *)field_strings;
8123 				g_free((gchar *)unit->singular);
8124 				g_free((gchar *)unit->plural);
8125 			} else if (field_display & BASE_RANGE_STRING) {
8126 				range_string *rs = (range_string *)field_strings;
8127 				while (rs->strptr) {
8128 					g_free((gchar *)rs->strptr);
8129 					rs++;
8130 				}
8131 			} else {
8132 				value_string *vs = (value_string *)field_strings;
8133 				while (vs->strptr) {
8134 					g_free((gchar *)vs->strptr);
8135 					vs++;
8136 				}
8137 			}
8138 			break;
8139 		default:
8140 			break;
8141 		}
8142 	}
8143 
8144 	if (field_type != FT_FRAMENUM) {
8145 		g_free((void *)field_strings);
8146 	}
8147 }
8148 
8149 static void
free_deregistered_field(gpointer data,gpointer user_data _U_)8150 free_deregistered_field (gpointer data, gpointer user_data _U_)
8151 {
8152 	header_field_info *hfi = (header_field_info *) data;
8153 	gint hf_id = hfi->id;
8154 
8155 	g_free((char *)hfi->name);
8156 	g_free((char *)hfi->abbrev);
8157 	g_free((char *)hfi->blurb);
8158 
8159 	proto_free_field_strings(hfi->type, hfi->display, hfi->strings);
8160 
8161 	if (hfi->parent == -1)
8162 		g_slice_free(header_field_info, hfi);
8163 
8164 	gpa_hfinfo.hfi[hf_id] = NULL; /* Invalidate this hf_id / proto_id */
8165 }
8166 
8167 static void
free_deregistered_data(gpointer data,gpointer user_data _U_)8168 free_deregistered_data (gpointer data, gpointer user_data _U_)
8169 {
8170 	g_free (data);
8171 }
8172 
8173 static void
free_deregistered_slice(gpointer data,gpointer user_data _U_)8174 free_deregistered_slice (gpointer data, gpointer user_data _U_)
8175 {
8176 	struct g_slice_data *slice_data = (struct g_slice_data *)data;
8177 
8178 	g_slice_free1(slice_data->block_size, slice_data->mem_block);
8179 	g_slice_free(struct g_slice_data, slice_data);
8180 }
8181 
8182 /* free deregistered fields and data */
8183 void
proto_free_deregistered_fields(void)8184 proto_free_deregistered_fields (void)
8185 {
8186 	expert_free_deregistered_expertinfos();
8187 
8188 	g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL);
8189 	g_ptr_array_free(deregistered_fields, TRUE);
8190 	deregistered_fields = g_ptr_array_new();
8191 
8192 	g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL);
8193 	g_ptr_array_free(deregistered_data, TRUE);
8194 	deregistered_data = g_ptr_array_new();
8195 
8196 	g_ptr_array_foreach(deregistered_slice, free_deregistered_slice, NULL);
8197 	g_ptr_array_free(deregistered_slice, TRUE);
8198 	deregistered_slice = g_ptr_array_new();
8199 }
8200 
8201 /* chars allowed in field abbrev: alphanumerics, '-', "_", and ".". */
8202 static
8203 const guint8 fld_abbrev_chars[256] = {
8204 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00-0x0F */
8205 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10-0x1F */
8206 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, /* 0x20-0x2F '-', '.'	   */
8207 	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 0x30-0x3F '0'-'9'	   */
8208 	0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40-0x4F 'A'-'O'	   */
8209 	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 0x50-0x5F 'P'-'Z', '_' */
8210 	0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x60-0x6F 'a'-'o'	   */
8211 	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 0x70-0x7F 'p'-'z'	   */
8212 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80-0x8F */
8213 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90-0x9F */
8214 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xA0-0xAF */
8215 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xB0-0xBF */
8216 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xC0-0xCF */
8217 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xD0-0xDF */
8218 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xE0-0xEF */
8219 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xF0-0xFF */
8220 };
8221 
8222 static const value_string hf_display[] = {
8223 	{ BASE_NONE,			  "BASE_NONE"			   },
8224 	{ BASE_DEC,			  "BASE_DEC"			   },
8225 	{ BASE_HEX,			  "BASE_HEX"			   },
8226 	{ BASE_OCT,			  "BASE_OCT"			   },
8227 	{ BASE_DEC_HEX,			  "BASE_DEC_HEX"		   },
8228 	{ BASE_HEX_DEC,			  "BASE_HEX_DEC"		   },
8229 	{ BASE_CUSTOM,			  "BASE_CUSTOM"			   },
8230 	{ BASE_NONE|BASE_RANGE_STRING,    "BASE_NONE|BASE_RANGE_STRING"	   },
8231 	{ BASE_DEC|BASE_RANGE_STRING,     "BASE_DEC|BASE_RANGE_STRING"	   },
8232 	{ BASE_HEX|BASE_RANGE_STRING,     "BASE_HEX|BASE_RANGE_STRING"	   },
8233 	{ BASE_OCT|BASE_RANGE_STRING,     "BASE_OCT|BASE_RANGE_STRING"	   },
8234 	{ BASE_DEC_HEX|BASE_RANGE_STRING, "BASE_DEC_HEX|BASE_RANGE_STRING" },
8235 	{ BASE_HEX_DEC|BASE_RANGE_STRING, "BASE_HEX_DEC|BASE_RANGE_STRING" },
8236 	{ BASE_CUSTOM|BASE_RANGE_STRING,  "BASE_CUSTOM|BASE_RANGE_STRING"  },
8237 	{ BASE_NONE|BASE_VAL64_STRING,    "BASE_NONE|BASE_VAL64_STRING"	   },
8238 	{ BASE_DEC|BASE_VAL64_STRING,     "BASE_DEC|BASE_VAL64_STRING"	   },
8239 	{ BASE_HEX|BASE_VAL64_STRING,     "BASE_HEX|BASE_VAL64_STRING"	   },
8240 	{ BASE_OCT|BASE_VAL64_STRING,     "BASE_OCT|BASE_VAL64_STRING"	   },
8241 	{ BASE_DEC_HEX|BASE_VAL64_STRING, "BASE_DEC_HEX|BASE_VAL64_STRING" },
8242 	{ BASE_HEX_DEC|BASE_VAL64_STRING, "BASE_HEX_DEC|BASE_VAL64_STRING" },
8243 	{ BASE_CUSTOM|BASE_VAL64_STRING,  "BASE_CUSTOM|BASE_VAL64_STRING"  },
8244 	/* Alias: BASE_NONE { BASE_FLOAT,			"BASE_FLOAT" }, */
8245 	/* Alias: BASE_NONE { STR_ASCII,			  "STR_ASCII" }, */
8246 	{ STR_UNICODE,			  "STR_UNICODE" },
8247 	{ ABSOLUTE_TIME_LOCAL,		  "ABSOLUTE_TIME_LOCAL"		   },
8248 	{ ABSOLUTE_TIME_UTC,		  "ABSOLUTE_TIME_UTC"		   },
8249 	{ ABSOLUTE_TIME_DOY_UTC,	  "ABSOLUTE_TIME_DOY_UTC"	   },
8250 	{ BASE_PT_UDP,			  "BASE_PT_UDP"			   },
8251 	{ BASE_PT_TCP,			  "BASE_PT_TCP"			   },
8252 	{ BASE_PT_DCCP,			  "BASE_PT_DCCP"		   },
8253 	{ BASE_PT_SCTP,			  "BASE_PT_SCTP"		   },
8254 	{ BASE_OUI,			  "BASE_OUI"			   },
8255 	{ 0,				  NULL } };
8256 
proto_field_display_to_string(int field_display)8257 const char* proto_field_display_to_string(int field_display)
8258 {
8259 	return val_to_str_const(field_display, hf_display, "Unknown");
8260 }
8261 
8262 static inline port_type
display_to_port_type(field_display_e e)8263 display_to_port_type(field_display_e e)
8264 {
8265 	switch (e) {
8266 	case BASE_PT_UDP:
8267 		return PT_UDP;
8268 	case BASE_PT_TCP:
8269 		return PT_TCP;
8270 	case BASE_PT_DCCP:
8271 		return PT_DCCP;
8272 	case BASE_PT_SCTP:
8273 		return PT_SCTP;
8274 	default:
8275 		break;
8276 	}
8277 	return PT_NONE;
8278 }
8279 
8280 /* temporary function containing assert part for easier profiling */
8281 static void
tmp_fld_check_assert(header_field_info * hfinfo)8282 tmp_fld_check_assert(header_field_info *hfinfo)
8283 {
8284 	gchar* tmp_str;
8285 
8286 	/* The field must have a name (with length > 0) */
8287 	if (!hfinfo->name || !hfinfo->name[0]) {
8288 		if (hfinfo->abbrev)
8289 			/* Try to identify the field */
8290 			ws_error("Field (abbrev='%s') does not have a name\n",
8291 				hfinfo->abbrev);
8292 		else
8293 			/* Hum, no luck */
8294 			ws_error("Field does not have a name (nor an abbreviation)\n");
8295 	}
8296 
8297 	/* fields with an empty string for an abbreviation aren't filterable */
8298 	if (!hfinfo->abbrev || !hfinfo->abbrev[0])
8299 		ws_error("Field '%s' does not have an abbreviation\n", hfinfo->name);
8300 
8301 	/*  These types of fields are allowed to have value_strings,
8302 	 *  true_false_strings or a protocol_t struct
8303 	 */
8304 	if (hfinfo->strings != NULL) {
8305 		switch (hfinfo->type) {
8306 		case FT_CHAR:
8307 		case FT_UINT8:
8308 		case FT_UINT16:
8309 		case FT_UINT24:
8310 		case FT_UINT32:
8311 		case FT_UINT40:
8312 		case FT_UINT48:
8313 		case FT_UINT56:
8314 		case FT_UINT64:
8315 		case FT_INT8:
8316 		case FT_INT16:
8317 		case FT_INT24:
8318 		case FT_INT32:
8319 		case FT_INT40:
8320 		case FT_INT48:
8321 		case FT_INT56:
8322 		case FT_INT64:
8323 		case FT_BOOLEAN:
8324 		case FT_PROTOCOL:
8325 		case FT_FRAMENUM:
8326 			break;
8327 		case FT_FLOAT:
8328 		case FT_DOUBLE:
8329 			//allowed to support string if its a unit decsription
8330 			if (hfinfo->display & BASE_UNIT_STRING)
8331 				break;
8332 
8333 			//fallthrough
8334 		case FT_BYTES:
8335 			//allowed to support string if its a protocol (for pinos)
8336 			if (hfinfo->display & BASE_PROTOCOL_INFO)
8337 				break;
8338 
8339 			//fallthrough
8340 		default:
8341 			ws_error("Field '%s' (%s) has a 'strings' value but is of type %s"
8342 				" (which is not allowed to have strings)\n",
8343 				hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type));
8344 		}
8345 	}
8346 
8347 	/* TODO: This check may slow down startup, and output quite a few warnings.
8348 	   It would be good to be able to enable this (and possibly other checks?)
8349 	   in non-release builds.   */
8350 #ifdef ENABLE_CHECK_FILTER
8351 	/* Check for duplicate value_string values.
8352 	   There are lots that have the same value *and* string, so for now only
8353 	   report those that have same value but different string. */
8354 	if ((hfinfo->strings != NULL) &&
8355 	    !(hfinfo->display & BASE_RANGE_STRING) &&
8356 	    !(hfinfo->display & BASE_UNIT_STRING) &&
8357 	    !((hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_CUSTOM) &&
8358 	    (
8359 		    (hfinfo->type == FT_CHAR)  ||
8360 		    (hfinfo->type == FT_UINT8)  ||
8361 		    (hfinfo->type == FT_UINT16) ||
8362 		    (hfinfo->type == FT_UINT24) ||
8363 		    (hfinfo->type == FT_UINT32) ||
8364 		    (hfinfo->type == FT_INT8)   ||
8365 		    (hfinfo->type == FT_INT16)  ||
8366 		    (hfinfo->type == FT_INT24)  ||
8367 		    (hfinfo->type == FT_INT32)  )) {
8368 
8369 		if (hfinfo->display & BASE_EXT_STRING) {
8370 			if (hfinfo->display & BASE_VAL64_STRING) {
8371 				const val64_string *start_values = VAL64_STRING_EXT_VS_P((const val64_string_ext*)hfinfo->strings);
8372 				CHECK_HF_VALUE(val64_string, G_GINT64_MODIFIER, start_values);
8373 			} else {
8374 				const value_string *start_values = VALUE_STRING_EXT_VS_P((const value_string_ext*)hfinfo->strings);
8375 				CHECK_HF_VALUE(value_string, "", start_values);
8376 			}
8377 		} else {
8378 			const value_string *start_values = (const value_string*)hfinfo->strings;
8379 			CHECK_HF_VALUE(value_string, "", start_values);
8380 		}
8381 	}
8382 
8383 	if (hfinfo->type == FT_BOOLEAN) {
8384 		const true_false_string *tfs = (const true_false_string*)hfinfo->strings;
8385 		if (tfs) {
8386 			if (strcmp(tfs->false_string, tfs->true_string) == 0) {
8387 				ws_warning("Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")",
8388 						   hfinfo->name, hfinfo->abbrev,
8389 						   tfs->false_string, tfs->true_string);
8390 			}
8391 		}
8392 	}
8393 
8394 	if (hfinfo->display & BASE_RANGE_STRING) {
8395 		const range_string *rs = (const range_string*)(hfinfo->strings);
8396 		if (rs) {
8397 			const range_string *this_it = rs;
8398 
8399 			do {
8400 				if (this_it->value_max < this_it->value_min) {
8401 					ws_warning("value_range_string error:  %s (%s) entry for \"%s\" - max(%u 0x%x) is less than min(%u 0x%x)",
8402 							  hfinfo->name, hfinfo->abbrev,
8403 							  this_it->strptr,
8404 							  this_it->value_max, this_it->value_max,
8405 							  this_it->value_min, this_it->value_min);
8406 					++this_it;
8407 					continue;
8408 				}
8409 
8410 				for (const range_string *prev_it=rs; prev_it < this_it; ++prev_it) {
8411 					/* Not OK if this one is completely hidden by an earlier one! */
8412 					if ((prev_it->value_min <= this_it->value_min) && (prev_it->value_max >= this_it->value_max)) {
8413 						ws_warning("value_range_string error:  %s (%s) hidden by earlier entry "
8414 								  "(prev=\"%s\":  %u 0x%x -> %u 0x%x)  (this=\"%s\":  %u 0x%x -> %u 0x%x)",
8415 								  hfinfo->name, hfinfo->abbrev,
8416 								  prev_it->strptr, prev_it->value_min, prev_it->value_min,
8417 								  prev_it->value_max, prev_it->value_max,
8418 								  this_it->strptr, this_it->value_min, this_it->value_min,
8419 								  this_it->value_max, this_it->value_max);
8420 					}
8421 				}
8422 				++this_it;
8423 			} while (this_it->strptr);
8424 		}
8425 	}
8426 #endif
8427 
8428 	switch (hfinfo->type) {
8429 
8430 		case FT_CHAR:
8431 			/*  Require the char type to have BASE_HEX, BASE_OCT,
8432 			 *  BASE_CUSTOM, or BASE_NONE as its base.
8433 			 *
8434 			 *  If the display value is BASE_NONE and there is a
8435 			 *  strings conversion then the dissector writer is
8436 			 *  telling us that the field's numerical value is
8437 			 *  meaningless; we'll avoid showing the value to the
8438 			 *  user.
8439 			 */
8440 			switch (FIELD_DISPLAY(hfinfo->display)) {
8441 				case BASE_HEX:
8442 				case BASE_OCT:
8443 				case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
8444 					break;
8445 				case BASE_NONE:
8446 					if (hfinfo->strings == NULL)
8447 						ws_error("Field '%s' (%s) is an integral value (%s)"
8448 							" but is being displayed as BASE_NONE but"
8449 							" without a strings conversion",
8450 							hfinfo->name, hfinfo->abbrev,
8451 							ftype_name(hfinfo->type));
8452 					break;
8453 				default:
8454 					tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
8455 					ws_error("Field '%s' (%s) is a character value (%s)"
8456 						" but is being displayed as %s\n",
8457 						hfinfo->name, hfinfo->abbrev,
8458 						ftype_name(hfinfo->type), tmp_str);
8459 					wmem_free(NULL, tmp_str);
8460 			}
8461 			if (hfinfo->display & BASE_UNIT_STRING) {
8462 				ws_error("Field '%s' (%s) is a character value (%s) but has a unit string\n",
8463 					hfinfo->name, hfinfo->abbrev,
8464 					ftype_name(hfinfo->type));
8465 			}
8466 			break;
8467 		case FT_INT8:
8468 		case FT_INT16:
8469 		case FT_INT24:
8470 		case FT_INT32:
8471 		case FT_INT40:
8472 		case FT_INT48:
8473 		case FT_INT56:
8474 		case FT_INT64:
8475 			/*	Hexadecimal and octal are, in printf() and everywhere
8476 			 *	else, unsigned so don't allow dissectors to register a
8477 			 *	signed field to be displayed unsigned.  (Else how would
8478 			 *	we display negative values?)
8479 			 */
8480 			switch (FIELD_DISPLAY(hfinfo->display)) {
8481 				case BASE_HEX:
8482 				case BASE_OCT:
8483 				case BASE_DEC_HEX:
8484 				case BASE_HEX_DEC:
8485 					tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
8486 					ws_error("Field '%s' (%s) is signed (%s) but is being displayed unsigned (%s)\n",
8487 						hfinfo->name, hfinfo->abbrev,
8488 						ftype_name(hfinfo->type), tmp_str);
8489 					wmem_free(NULL, tmp_str);
8490 			}
8491 			/* FALL THROUGH */
8492 		case FT_UINT8:
8493 		case FT_UINT16:
8494 		case FT_UINT24:
8495 		case FT_UINT32:
8496 		case FT_UINT40:
8497 		case FT_UINT48:
8498 		case FT_UINT56:
8499 		case FT_UINT64:
8500 			if (IS_BASE_PORT(hfinfo->display)) {
8501 				tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
8502 				if (hfinfo->type != FT_UINT16) {
8503 					ws_error("Field '%s' (%s) has 'display' value %s but it can only be used with FT_UINT16, not %s\n",
8504 						hfinfo->name, hfinfo->abbrev,
8505 						tmp_str, ftype_name(hfinfo->type));
8506 				}
8507 				if (hfinfo->strings != NULL) {
8508 					ws_error("Field '%s' (%s) is an %s (%s) but has a strings value\n",
8509 						hfinfo->name, hfinfo->abbrev,
8510 						ftype_name(hfinfo->type), tmp_str);
8511 				}
8512 				if (hfinfo->bitmask != 0) {
8513 					ws_error("Field '%s' (%s) is an %s (%s) but has a bitmask\n",
8514 						hfinfo->name, hfinfo->abbrev,
8515 						ftype_name(hfinfo->type), tmp_str);
8516 				}
8517 				wmem_free(NULL, tmp_str);
8518 				break;
8519 			}
8520 
8521 			if (hfinfo->display == BASE_OUI) {
8522 				tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
8523 				if (hfinfo->type != FT_UINT24) {
8524 					ws_error("Field '%s' (%s) has 'display' value %s but it can only be used with FT_UINT24, not %s\n",
8525 						hfinfo->name, hfinfo->abbrev,
8526 						tmp_str, ftype_name(hfinfo->type));
8527 				}
8528 				if (hfinfo->strings != NULL) {
8529 					ws_error("Field '%s' (%s) is an %s (%s) but has a strings value\n",
8530 						hfinfo->name, hfinfo->abbrev,
8531 						ftype_name(hfinfo->type), tmp_str);
8532 				}
8533 				if (hfinfo->bitmask != 0) {
8534 					ws_error("Field '%s' (%s) is an %s (%s) but has a bitmask\n",
8535 						hfinfo->name, hfinfo->abbrev,
8536 						ftype_name(hfinfo->type), tmp_str);
8537 				}
8538 				wmem_free(NULL, tmp_str);
8539 				break;
8540 			}
8541 
8542 			/*  Require integral types (other than frame number,
8543 			 *  which is always displayed in decimal) to have a
8544 			 *  number base.
8545 			 *
8546 			 *  If the display value is BASE_NONE and there is a
8547 			 *  strings conversion then the dissector writer is
8548 			 *  telling us that the field's numerical value is
8549 			 *  meaningless; we'll avoid showing the value to the
8550 			 *  user.
8551 			 */
8552 			switch (FIELD_DISPLAY(hfinfo->display)) {
8553 				case BASE_DEC:
8554 				case BASE_HEX:
8555 				case BASE_OCT:
8556 				case BASE_DEC_HEX:
8557 				case BASE_HEX_DEC:
8558 				case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
8559 					break;
8560 				case BASE_NONE:
8561 					if (hfinfo->strings == NULL) {
8562 						ws_error("Field '%s' (%s) is an integral value (%s)"
8563 							" but is being displayed as BASE_NONE but"
8564 							" without a strings conversion",
8565 							hfinfo->name, hfinfo->abbrev,
8566 							ftype_name(hfinfo->type));
8567 					}
8568 					if (hfinfo->display & BASE_SPECIAL_VALS) {
8569 						ws_error("Field '%s' (%s) is an integral value (%s)"
8570 							" that is being displayed as BASE_NONE but"
8571 							" with BASE_SPECIAL_VALS",
8572 							hfinfo->name, hfinfo->abbrev,
8573 							ftype_name(hfinfo->type));
8574 					}
8575 					break;
8576 
8577 				default:
8578 					tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
8579 					ws_error("Field '%s' (%s) is an integral value (%s)"
8580 						" but is being displayed as %s\n",
8581 						hfinfo->name, hfinfo->abbrev,
8582 						ftype_name(hfinfo->type), tmp_str);
8583 					wmem_free(NULL, tmp_str);
8584 			}
8585 			break;
8586 		case FT_BYTES:
8587 		case FT_UINT_BYTES:
8588 			/*  Require bytes to have a "display type" that could
8589 			 *  add a character between displayed bytes.
8590 			 */
8591 			switch (FIELD_DISPLAY(hfinfo->display)) {
8592 				case BASE_NONE:
8593 				case SEP_DOT:
8594 				case SEP_DASH:
8595 				case SEP_COLON:
8596 				case SEP_SPACE:
8597 					break;
8598 				default:
8599 					tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
8600 					ws_error("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\n",
8601 						hfinfo->name, hfinfo->abbrev, tmp_str);
8602 					wmem_free(NULL, tmp_str);
8603 			}
8604 			if (hfinfo->bitmask != 0)
8605 				ws_error("Field '%s' (%s) is an %s but has a bitmask\n",
8606 					hfinfo->name, hfinfo->abbrev,
8607 					ftype_name(hfinfo->type));
8608 			//allowed to support string if its a protocol (for pinos)
8609 			if ((hfinfo->strings != NULL) && (!(hfinfo->display & BASE_PROTOCOL_INFO)))
8610 				ws_error("Field '%s' (%s) is an %s but has a strings value\n",
8611 					hfinfo->name, hfinfo->abbrev,
8612 					ftype_name(hfinfo->type));
8613 			break;
8614 
8615 		case FT_PROTOCOL:
8616 		case FT_FRAMENUM:
8617 			if (hfinfo->display != BASE_NONE) {
8618 				tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
8619 				ws_error("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE\n",
8620 					hfinfo->name, hfinfo->abbrev,
8621 					ftype_name(hfinfo->type), tmp_str);
8622 				wmem_free(NULL, tmp_str);
8623 			}
8624 			if (hfinfo->bitmask != 0)
8625 				ws_error("Field '%s' (%s) is an %s but has a bitmask\n",
8626 					hfinfo->name, hfinfo->abbrev,
8627 					ftype_name(hfinfo->type));
8628 			break;
8629 
8630 		case FT_BOOLEAN:
8631 			break;
8632 
8633 		case FT_ABSOLUTE_TIME:
8634 			if (!(hfinfo->display == ABSOLUTE_TIME_LOCAL ||
8635 			      hfinfo->display == ABSOLUTE_TIME_UTC   ||
8636 			      hfinfo->display == ABSOLUTE_TIME_NTP_UTC   ||
8637 			      hfinfo->display == ABSOLUTE_TIME_DOY_UTC)) {
8638 				tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
8639 				ws_error("Field '%s' (%s) is a %s but is being displayed as %s instead of as a time\n",
8640 					hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type), tmp_str);
8641 				wmem_free(NULL, tmp_str);
8642 			}
8643 			if (hfinfo->bitmask != 0)
8644 				ws_error("Field '%s' (%s) is an %s but has a bitmask\n",
8645 					hfinfo->name, hfinfo->abbrev,
8646 					ftype_name(hfinfo->type));
8647 			break;
8648 
8649 		case FT_STRING:
8650 		case FT_STRINGZ:
8651 		case FT_UINT_STRING:
8652 		case FT_STRINGZPAD:
8653 		case FT_STRINGZTRUNC:
8654 			switch (hfinfo->display) {
8655 				case STR_ASCII:
8656 				case STR_UNICODE:
8657 					break;
8658 
8659 				default:
8660 					tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
8661 					ws_error("Field '%s' (%s) is an string value (%s)"
8662 						" but is being displayed as %s\n",
8663 						hfinfo->name, hfinfo->abbrev,
8664 						ftype_name(hfinfo->type), tmp_str);
8665 					wmem_free(NULL, tmp_str);
8666 			}
8667 
8668 			if (hfinfo->bitmask != 0)
8669 				ws_error("Field '%s' (%s) is an %s but has a bitmask\n",
8670 					hfinfo->name, hfinfo->abbrev,
8671 					ftype_name(hfinfo->type));
8672 			if (hfinfo->strings != NULL)
8673 				ws_error("Field '%s' (%s) is an %s but has a strings value\n",
8674 					hfinfo->name, hfinfo->abbrev,
8675 					ftype_name(hfinfo->type));
8676 			break;
8677 
8678 		case FT_IPv4:
8679 			switch (hfinfo->display) {
8680 				case BASE_NONE:
8681 				case BASE_NETMASK:
8682 					break;
8683 
8684 				default:
8685 					tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
8686 					ws_error("Field '%s' (%s) is an IPv4 value (%s)"
8687 						" but is being displayed as %s\n",
8688 						hfinfo->name, hfinfo->abbrev,
8689 						ftype_name(hfinfo->type), tmp_str);
8690 					wmem_free(NULL, tmp_str);
8691 					break;
8692 			}
8693 			break;
8694 		case FT_FLOAT:
8695 		case FT_DOUBLE:
8696 			if (FIELD_DISPLAY(hfinfo->display) != BASE_NONE) {
8697 				tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
8698 				ws_error("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE\n",
8699 					hfinfo->name, hfinfo->abbrev,
8700 					ftype_name(hfinfo->type),
8701 					tmp_str);
8702 				wmem_free(NULL, tmp_str);
8703 			}
8704 			if (hfinfo->bitmask != 0)
8705 				ws_error("Field '%s' (%s) is an %s but has a bitmask\n",
8706 					hfinfo->name, hfinfo->abbrev,
8707 					ftype_name(hfinfo->type));
8708 			if ((hfinfo->strings != NULL) && (!(hfinfo->display & BASE_UNIT_STRING)))
8709 				ws_error("Field '%s' (%s) is an %s but has a strings value\n",
8710 					hfinfo->name, hfinfo->abbrev,
8711 					ftype_name(hfinfo->type));
8712 			break;
8713 		default:
8714 			if (hfinfo->display != BASE_NONE) {
8715 				tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
8716 				ws_error("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE\n",
8717 					hfinfo->name, hfinfo->abbrev,
8718 					ftype_name(hfinfo->type),
8719 					tmp_str);
8720 				wmem_free(NULL, tmp_str);
8721 			}
8722 			if (hfinfo->bitmask != 0)
8723 				ws_error("Field '%s' (%s) is an %s but has a bitmask\n",
8724 					hfinfo->name, hfinfo->abbrev,
8725 					ftype_name(hfinfo->type));
8726 			if (hfinfo->strings != NULL)
8727 				ws_error("Field '%s' (%s) is an %s but has a strings value\n",
8728 					hfinfo->name, hfinfo->abbrev,
8729 					ftype_name(hfinfo->type));
8730 			break;
8731 	}
8732 }
8733 
8734 #ifdef ENABLE_CHECK_FILTER
8735 static enum ftenum
_ftype_common(enum ftenum type)8736 _ftype_common(enum ftenum type)
8737 {
8738 	switch (type) {
8739 		case FT_INT8:
8740 		case FT_INT16:
8741 		case FT_INT24:
8742 		case FT_INT32:
8743 			return FT_INT32;
8744 
8745 		case FT_CHAR:
8746 		case FT_UINT8:
8747 		case FT_UINT16:
8748 		case FT_UINT24:
8749 		case FT_UINT32:
8750 		case FT_IPXNET:
8751 		case FT_FRAMENUM:
8752 			return FT_UINT32;
8753 
8754 		case FT_UINT64:
8755 		case FT_EUI64:
8756 			return FT_UINT64;
8757 
8758 		case FT_STRING:
8759 		case FT_STRINGZ:
8760 		case FT_UINT_STRING:
8761 			return FT_STRING;
8762 
8763 		case FT_FLOAT:
8764 		case FT_DOUBLE:
8765 			return FT_DOUBLE;
8766 
8767 		case FT_BYTES:
8768 		case FT_UINT_BYTES:
8769 		case FT_ETHER:
8770 		case FT_OID:
8771 			return FT_BYTES;
8772 
8773 		case FT_ABSOLUTE_TIME:
8774 		case FT_RELATIVE_TIME:
8775 			return FT_ABSOLUTE_TIME;
8776 
8777 		default:
8778 			return type;
8779 	}
8780 }
8781 #endif
8782 
8783 static void
register_type_length_mismatch(void)8784 register_type_length_mismatch(void)
8785 {
8786 	static ei_register_info ei[] = {
8787 		{ &ei_type_length_mismatch_error, { "_ws.type_length.mismatch", PI_MALFORMED, PI_ERROR, "Trying to fetch X with length Y", EXPFILL }},
8788 		{ &ei_type_length_mismatch_warn, { "_ws.type_length.mismatch", PI_MALFORMED, PI_WARN, "Trying to fetch X with length Y", EXPFILL }},
8789 	};
8790 
8791 	expert_module_t* expert_type_length_mismatch;
8792 
8793 	proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
8794 
8795 	expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
8796 	expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei));
8797 
8798 	/* "Type Length Mismatch" isn't really a protocol, it's an error indication;
8799 	   disabling them makes no sense. */
8800 	proto_set_cant_toggle(proto_type_length_mismatch);
8801 }
8802 
8803 static void
register_number_string_decodinws_error(void)8804 register_number_string_decodinws_error(void)
8805 {
8806 	static ei_register_info ei[] = {
8807 		{ &ei_number_string_decoding_failed_error,
8808 			{ "_ws.number_string.decoding_error.failed", PI_MALFORMED, PI_ERROR,
8809 			  "Failed to decode number from string", EXPFILL
8810 			}
8811 		},
8812 		{ &ei_number_string_decoding_erange_error,
8813 			{ "_ws.number_string.decoding_error.erange", PI_MALFORMED, PI_ERROR,
8814 			  "Decoded number from string is out of valid range", EXPFILL
8815 			}
8816 		},
8817 	};
8818 
8819 	expert_module_t* expert_number_string_decoding_error;
8820 
8821 	proto_number_string_decoding_error =
8822 		proto_register_protocol("Number-String Decoding Error",
8823 					"Number-string decoding error",
8824 					"_ws.number_string.decoding_error");
8825 
8826 	expert_number_string_decoding_error =
8827 		expert_register_protocol(proto_number_string_decoding_error);
8828 	expert_register_field_array(expert_number_string_decoding_error, ei, array_length(ei));
8829 
8830 	/* "Number-String Decoding Error" isn't really a protocol, it's an error indication;
8831 	   disabling them makes no sense. */
8832 	proto_set_cant_toggle(proto_number_string_decoding_error);
8833 }
8834 
8835 static void
register_string_errors(void)8836 register_string_errors(void)
8837 {
8838 	static ei_register_info ei[] = {
8839 		{ &ei_string_trailing_characters,
8840 			{ "_ws.string.trailing_stray_characters", PI_UNDECODED, PI_WARN, "Trailing stray characters", EXPFILL }
8841 		},
8842 	};
8843 
8844 	expert_module_t* expert_string_errors;
8845 
8846 	proto_string_errors = proto_register_protocol("String Errors", "String errors", "_ws.string");
8847 
8848 	expert_string_errors = expert_register_protocol(proto_string_errors);
8849 	expert_register_field_array(expert_string_errors, ei, array_length(ei));
8850 
8851 	/* "String Errors" isn't really a protocol, it's an error indication;
8852 	   disabling them makes no sense. */
8853 	proto_set_cant_toggle(proto_string_errors);
8854 }
8855 
8856 #define PROTO_PRE_ALLOC_HF_FIELDS_MEM (235000+PRE_ALLOC_EXPERT_FIELDS_MEM)
8857 static int
proto_register_field_init(header_field_info * hfinfo,const int parent)8858 proto_register_field_init(header_field_info *hfinfo, const int parent)
8859 {
8860 
8861 	tmp_fld_check_assert(hfinfo);
8862 
8863 	hfinfo->parent         = parent;
8864 	hfinfo->same_name_next = NULL;
8865 	hfinfo->same_name_prev_id = -1;
8866 
8867 	/* if we always add and never delete, then id == len - 1 is correct */
8868 	if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
8869 		if (!gpa_hfinfo.hfi) {
8870 			gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM;
8871 			gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM);
8872 		} else {
8873 			gpa_hfinfo.allocated_len += 1000;
8874 			gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
8875 						   sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
8876 			/*ws_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
8877 		}
8878 	}
8879 	gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
8880 	gpa_hfinfo.len++;
8881 	hfinfo->id = gpa_hfinfo.len - 1;
8882 
8883 	/* if we have real names, enter this field in the name tree */
8884 	if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) {
8885 
8886 		header_field_info *same_name_next_hfinfo;
8887 		guchar c;
8888 
8889 		/* Check that the filter name (abbreviation) is legal;
8890 		 * it must contain only alphanumerics, '-', "_", and ".". */
8891 		c = proto_check_field_name(hfinfo->abbrev);
8892 		if (c) {
8893 			if (c == '.') {
8894 				fprintf(stderr, "Invalid leading, duplicated or trailing '.' found in filter name '%s'\n", hfinfo->abbrev);
8895 			} else if (g_ascii_isprint(c)) {
8896 				fprintf(stderr, "Invalid character '%c' in filter name '%s'\n", c, hfinfo->abbrev);
8897 			} else {
8898 				fprintf(stderr, "Invalid byte \\%03o in filter name '%s'\n", c, hfinfo->abbrev);
8899 			}
8900 			DISSECTOR_ASSERT_NOT_REACHED();
8901 		}
8902 
8903 		/* We allow multiple hfinfo's to be registered under the same
8904 		 * abbreviation. This was done for X.25, as, depending
8905 		 * on whether it's modulo-8 or modulo-128 operation,
8906 		 * some bitfield fields may be in different bits of
8907 		 * a byte, and we want to be able to refer to that field
8908 		 * with one name regardless of whether the packets
8909 		 * are modulo-8 or modulo-128 packets. */
8910 
8911 		same_name_hfinfo = NULL;
8912 
8913 		g_hash_table_insert(gpa_name_map, (gpointer) (hfinfo->abbrev), hfinfo);
8914 		/* GLIB 2.x - if it is already present
8915 		 * the previous hfinfo with the same name is saved
8916 		 * to same_name_hfinfo by value destroy callback */
8917 		if (same_name_hfinfo) {
8918 			/* There's already a field with this name.
8919 			 * Put the current field *before* that field
8920 			 * in the list of fields with this name, Thus,
8921 			 * we end up with an effectively
8922 			 * doubly-linked-list of same-named hfinfo's,
8923 			 * with the head of the list (stored in the
8924 			 * hash) being the last seen hfinfo.
8925 			 */
8926 			same_name_next_hfinfo =
8927 				same_name_hfinfo->same_name_next;
8928 
8929 			hfinfo->same_name_next = same_name_next_hfinfo;
8930 			if (same_name_next_hfinfo)
8931 				same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
8932 
8933 			same_name_hfinfo->same_name_next = hfinfo;
8934 			hfinfo->same_name_prev_id = same_name_hfinfo->id;
8935 #ifdef ENABLE_CHECK_FILTER
8936 			while (same_name_hfinfo) {
8937 				if (_ftype_common(hfinfo->type) != _ftype_common(same_name_hfinfo->type))
8938 					ws_warning("'%s' exists multiple times with incompatible types: %s and %s", hfinfo->abbrev, ftype_name(hfinfo->type), ftype_name(same_name_hfinfo->type));
8939 				same_name_hfinfo = same_name_hfinfo->same_name_next;
8940 			}
8941 #endif
8942 		}
8943 	}
8944 
8945 	return hfinfo->id;
8946 }
8947 
8948 void
proto_register_subtree_array(gint * const * indices,const int num_indices)8949 proto_register_subtree_array(gint * const *indices, const int num_indices)
8950 {
8951 	int	i;
8952 	gint	*const *ptr = indices;
8953 
8954 	/*
8955 	 * If we've already allocated the array of tree types, expand
8956 	 * it; this lets plugins such as mate add tree types after
8957 	 * the initial startup.  (If we haven't already allocated it,
8958 	 * we don't allocate it; on the first pass, we just assign
8959 	 * ett values and keep track of how many we've assigned, and
8960 	 * when we're finished registering all dissectors we allocate
8961 	 * the array, so that we do only one allocation rather than
8962 	 * wasting CPU time and memory by growing the array for each
8963 	 * dissector that registers ett values.)
8964 	 */
8965 	if (tree_is_expanded != NULL) {
8966 		tree_is_expanded = (guint32 *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(guint32));
8967 
8968 		/* set new items to 0 */
8969 		/* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of guint32 to 0) */
8970 		for (i = num_tree_types; i < num_tree_types + num_indices; i++)
8971 			tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
8972 	}
8973 
8974 	/*
8975 	 * Assign "num_indices" subtree numbers starting at "num_tree_types",
8976 	 * returning the indices through the pointers in the array whose
8977 	 * first element is pointed to by "indices", and update
8978 	 * "num_tree_types" appropriately.
8979 	 */
8980 	for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
8981 		if (**ptr != -1) {
8982 			/* ws_error will terminate the program */
8983 			ws_error("register_subtree_array: subtree item type (ett_...) not -1 !"
8984 				" This is a development error:"
8985 				" Either the subtree item type has already been assigned or"
8986 				" was not initialized to -1.");
8987 		}
8988 		**ptr = num_tree_types;
8989 	}
8990 }
8991 
8992 static inline gsize
label_concat(char * label_str,gsize pos,const char * str)8993 label_concat(char *label_str, gsize pos, const char *str)
8994 {
8995 	if (pos < ITEM_LABEL_LENGTH)
8996 		pos += g_strlcpy(label_str + pos, str, ITEM_LABEL_LENGTH - pos);
8997 
8998 	return pos;
8999 }
9000 
9001 static void
label_mark_truncated(char * label_str,gsize name_pos)9002 label_mark_truncated(char *label_str, gsize name_pos)
9003 {
9004 	static const char  trunc_str[] = " [truncated]";
9005 	const size_t       trunc_len = sizeof(trunc_str)-1;
9006 	gchar             *last_char;
9007 
9008 	/* ..... field_name: dataaaaaaaaaaaaa
9009 	 *                 |
9010 	 *                 ^^^^^ name_pos
9011 	 *
9012 	 * ..... field_name [truncated]: dataaaaaaaaaaaaa
9013 	 *
9014 	 * name_pos==0 means that we have only data or only a field_name
9015 	 */
9016 
9017 	if (name_pos < ITEM_LABEL_LENGTH - trunc_len) {
9018 		memmove(label_str + name_pos + trunc_len, label_str + name_pos, ITEM_LABEL_LENGTH - name_pos - trunc_len);
9019 		memcpy(label_str + name_pos, trunc_str, trunc_len);
9020 
9021 		/* in general, label_str is UTF-8
9022 		   we can truncate it only at the beginning of a new character
9023 		   we go backwards from the byte right after our buffer and
9024 		    find the next starting byte of a UTF-8 character, this is
9025 		    where we cut
9026 		   there's no need to use g_utf8_find_prev_char(), the search
9027 		    will always succeed since we copied trunc_str into the
9028 		    buffer */
9029 		last_char = g_utf8_prev_char(&label_str[ITEM_LABEL_LENGTH - 1]);
9030 		*last_char = '\0';
9031 
9032 	} else if (name_pos < ITEM_LABEL_LENGTH)
9033 		(void) g_strlcpy(label_str + name_pos, trunc_str, ITEM_LABEL_LENGTH - name_pos);
9034 }
9035 
9036 static gsize
label_fill(char * label_str,gsize pos,const header_field_info * hfinfo,const char * text)9037 label_fill(char *label_str, gsize pos, const header_field_info *hfinfo, const char *text)
9038 {
9039 	gsize name_pos;
9040 
9041 	/* "%s: %s", hfinfo->name, text */
9042 	name_pos = pos = label_concat(label_str, pos, hfinfo->name);
9043 	if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE)) {
9044 		pos = label_concat(label_str, pos, ": ");
9045 		pos = label_concat(label_str, pos, text ? text : "(null)");
9046 	}
9047 
9048 	if (pos >= ITEM_LABEL_LENGTH) {
9049 		/* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
9050 		label_mark_truncated(label_str, name_pos);
9051 	}
9052 
9053 	return pos;
9054 }
9055 
9056 static gsize
label_fill_descr(char * label_str,gsize pos,const header_field_info * hfinfo,const char * text,const char * descr)9057 label_fill_descr(char *label_str, gsize pos, const header_field_info *hfinfo, const char *text, const char *descr)
9058 {
9059 	gsize name_pos;
9060 
9061 	/* "%s: %s (%s)", hfinfo->name, text, descr */
9062 	name_pos = pos = label_concat(label_str, pos, hfinfo->name);
9063 	if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE)) {
9064 		pos = label_concat(label_str, pos, ": ");
9065 		if (hfinfo->display & BASE_UNIT_STRING) {
9066 			pos = label_concat(label_str, pos, descr ? descr : "(null)");
9067 			pos = label_concat(label_str, pos, text ? text : "(null)");
9068 		} else {
9069 			pos = label_concat(label_str, pos, text ? text : "(null)");
9070 			pos = label_concat(label_str, pos, " (");
9071 			pos = label_concat(label_str, pos, descr ? descr : "(null)");
9072 			pos = label_concat(label_str, pos, ")");
9073 		}
9074 	}
9075 
9076 	if (pos >= ITEM_LABEL_LENGTH) {
9077 		/* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
9078 		label_mark_truncated(label_str, name_pos);
9079 	}
9080 
9081 	return pos;
9082 }
9083 
9084 void
proto_item_fill_label(field_info * fi,gchar * label_str)9085 proto_item_fill_label(field_info *fi, gchar *label_str)
9086 {
9087 	header_field_info  *hfinfo;
9088 	guint8		   *bytes;
9089 	guint32		    integer;
9090 	guint64		    integer64;
9091 	ws_in4_addr         ipv4;
9092 	e_guid_t	   *guid;
9093 	gchar		   *name;
9094 	address		    addr;
9095 	char		   *addr_str;
9096 	char		   *tmp;
9097 
9098 	if (!fi) {
9099 		if (label_str)
9100 			label_str[0]= '\0';
9101 		/* XXX: Check validity of hfinfo->type */
9102 		return;
9103 	}
9104 
9105 	hfinfo = fi->hfinfo;
9106 
9107 	switch (hfinfo->type) {
9108 		case FT_NONE:
9109 		case FT_PROTOCOL:
9110 			(void) g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH);
9111 			break;
9112 
9113 		case FT_BOOLEAN:
9114 			fill_label_boolean(fi, label_str);
9115 			break;
9116 
9117 		case FT_BYTES:
9118 		case FT_UINT_BYTES:
9119 			tmp = hfinfo_format_bytes(NULL, hfinfo,
9120 			    (guint8 *)fvalue_get(&fi->value),
9121 			    fvalue_length(&fi->value));
9122 			label_fill(label_str, 0, hfinfo, tmp);
9123 			wmem_free(NULL, tmp);
9124 			break;
9125 
9126 		case FT_CHAR:
9127 			if (hfinfo->bitmask) {
9128 				fill_label_bitfield_char(fi, label_str);
9129 			} else {
9130 				fill_label_char(fi, label_str);
9131 			}
9132 			break;
9133 
9134 		/* Four types of integers to take care of:
9135 		 *	Bitfield, with val_string
9136 		 *	Bitfield, w/o val_string
9137 		 *	Non-bitfield, with val_string
9138 		 *	Non-bitfield, w/o val_string
9139 		 */
9140 		case FT_UINT8:
9141 		case FT_UINT16:
9142 		case FT_UINT24:
9143 		case FT_UINT32:
9144 			if (hfinfo->bitmask) {
9145 				if (fi->flags & FI_VARINT) {
9146 					fill_label_bitfield_varint(fi, label_str, FALSE);
9147 				} else {
9148 					fill_label_bitfield(fi, label_str, FALSE);
9149 				}
9150 			} else {
9151 				fill_label_number(fi, label_str, FALSE);
9152 			}
9153 			break;
9154 
9155 		case FT_FRAMENUM:
9156 			fill_label_number(fi, label_str, FALSE);
9157 			break;
9158 
9159 		case FT_UINT40:
9160 		case FT_UINT48:
9161 		case FT_UINT56:
9162 		case FT_UINT64:
9163 			if (hfinfo->bitmask) {
9164 				if (fi->flags & FI_VARINT) {
9165 					fill_label_bitfield_varint64(fi, label_str, FALSE);
9166 				} else {
9167 					fill_label_bitfield64(fi, label_str, FALSE);
9168 				}
9169 			} else {
9170 				fill_label_number64(fi, label_str, FALSE);
9171 			}
9172 			break;
9173 
9174 		case FT_INT8:
9175 		case FT_INT16:
9176 		case FT_INT24:
9177 		case FT_INT32:
9178 			if (hfinfo->bitmask) {
9179 				if (fi->flags & FI_VARINT) {
9180 					fill_label_bitfield_varint(fi, label_str, TRUE);
9181 				} else {
9182 					fill_label_bitfield(fi, label_str, TRUE);
9183 				}
9184 			} else {
9185 				fill_label_number(fi, label_str, TRUE);
9186 			}
9187 			break;
9188 
9189 		case FT_INT40:
9190 		case FT_INT48:
9191 		case FT_INT56:
9192 		case FT_INT64:
9193 			if (hfinfo->bitmask) {
9194 				if (fi->flags & FI_VARINT) {
9195 					fill_label_bitfield_varint64(fi, label_str, TRUE);
9196 				} else {
9197 					fill_label_bitfield64(fi, label_str, TRUE);
9198 				}
9199 			} else {
9200 				fill_label_number64(fi, label_str, TRUE);
9201 			}
9202 			break;
9203 
9204 		case FT_FLOAT:
9205 		{
9206 			double d_value = fvalue_get_floating(&fi->value);
9207 			if (hfinfo->display & BASE_UNIT_STRING) {
9208 				g_snprintf(label_str, ITEM_LABEL_LENGTH,
9209 					   "%s: %." G_STRINGIFY(FLT_DIG) "g%s",
9210 					   hfinfo->name, d_value,
9211 					   unit_name_string_get_double(d_value, (const unit_name_string*)hfinfo->strings));
9212 			} else {
9213 				g_snprintf(label_str, ITEM_LABEL_LENGTH,
9214 					   "%s: %." G_STRINGIFY(FLT_DIG) "g",
9215 					   hfinfo->name, d_value);
9216 			}
9217 			break;
9218 		}
9219 
9220 		case FT_DOUBLE:
9221 		{
9222 			double d_value = fvalue_get_floating(&fi->value);
9223 			if (hfinfo->display & BASE_UNIT_STRING) {
9224 				g_snprintf(label_str, ITEM_LABEL_LENGTH,
9225 					   "%s: %." G_STRINGIFY(DBL_DIG) "g%s",
9226 					   hfinfo->name, d_value,
9227 					   unit_name_string_get_double(d_value, (const unit_name_string*)hfinfo->strings));
9228 			} else {
9229 				g_snprintf(label_str, ITEM_LABEL_LENGTH,
9230 					   "%s: %." G_STRINGIFY(DBL_DIG) "g",
9231 					   hfinfo->name, d_value);
9232 			}
9233 			break;
9234 		}
9235 
9236 		case FT_ABSOLUTE_TIME:
9237 			tmp = abs_time_to_str(NULL, (const nstime_t *)fvalue_get(&fi->value), (absolute_time_display_e)hfinfo->display, TRUE);
9238 			label_fill(label_str, 0, hfinfo, tmp);
9239 			wmem_free(NULL, tmp);
9240 			break;
9241 
9242 		case FT_RELATIVE_TIME:
9243 			tmp = rel_time_to_secs_str(NULL, (const nstime_t *)fvalue_get(&fi->value));
9244 			g_snprintf(label_str, ITEM_LABEL_LENGTH,
9245 				   "%s: %s seconds", hfinfo->name, tmp);
9246 			wmem_free(NULL, tmp);
9247 			break;
9248 
9249 		case FT_IPXNET:
9250 			integer = fvalue_get_uinteger(&fi->value);
9251 			tmp = get_ipxnet_name(NULL, integer);
9252 			g_snprintf(label_str, ITEM_LABEL_LENGTH,
9253 				   "%s: %s (0x%08X)", hfinfo->name,
9254 				   tmp, integer);
9255 			wmem_free(NULL, tmp);
9256 			break;
9257 
9258 		case FT_AX25:
9259 			addr.type = AT_AX25;
9260 			addr.len  = AX25_ADDR_LEN;
9261 			addr.data = (guint8 *)fvalue_get(&fi->value);
9262 
9263 			addr_str = (char*)address_to_str(NULL, &addr);
9264 			g_snprintf(label_str, ITEM_LABEL_LENGTH,
9265 				   "%s: %s", hfinfo->name, addr_str);
9266 			wmem_free(NULL, addr_str);
9267 			break;
9268 
9269 		case FT_VINES:
9270 			addr.type = AT_VINES;
9271 			addr.len  = VINES_ADDR_LEN;
9272 			addr.data = (guint8 *)fvalue_get(&fi->value);
9273 
9274 			addr_str = (char*)address_to_str(NULL, &addr);
9275 			g_snprintf(label_str, ITEM_LABEL_LENGTH,
9276 				   "%s: %s", hfinfo->name, addr_str);
9277 			wmem_free(NULL, addr_str);
9278 			break;
9279 
9280 		case FT_ETHER:
9281 			bytes = (guint8 *)fvalue_get(&fi->value);
9282 
9283 			addr.type = AT_ETHER;
9284 			addr.len  = 6;
9285 			addr.data = bytes;
9286 
9287 			addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
9288 			g_snprintf(label_str, ITEM_LABEL_LENGTH,
9289 				   "%s: %s", hfinfo->name, addr_str);
9290 			wmem_free(NULL, addr_str);
9291 			break;
9292 
9293 		case FT_IPv4:
9294 			ipv4 = fvalue_get_uinteger(&fi->value);
9295 
9296 			addr.type = AT_IPv4;
9297 			addr.len  = 4;
9298 			addr.data = &ipv4;
9299 
9300 			if (hfinfo->display == BASE_NETMASK) {
9301 				addr_str = (char*)address_to_str(NULL, &addr);
9302 			} else {
9303 				addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
9304 			}
9305 			g_snprintf(label_str, ITEM_LABEL_LENGTH,
9306 				   "%s: %s", hfinfo->name, addr_str);
9307 			wmem_free(NULL, addr_str);
9308 			break;
9309 
9310 		case FT_IPv6:
9311 			bytes = (guint8 *)fvalue_get(&fi->value);
9312 
9313 			addr.type = AT_IPv6;
9314 			addr.len  = 16;
9315 			addr.data = bytes;
9316 
9317 			addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
9318 			g_snprintf(label_str, ITEM_LABEL_LENGTH,
9319 				   "%s: %s", hfinfo->name, addr_str);
9320 			wmem_free(NULL, addr_str);
9321 			break;
9322 
9323 		case FT_FCWWN:
9324 			addr.type = AT_FCWWN;
9325 			addr.len  = FCWWN_ADDR_LEN;
9326 			addr.data = (guint8 *)fvalue_get(&fi->value);
9327 
9328 			addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
9329 			g_snprintf(label_str, ITEM_LABEL_LENGTH,
9330 				   "%s: %s", hfinfo->name, addr_str);
9331 			wmem_free(NULL, addr_str);
9332 			break;
9333 
9334 		case FT_GUID:
9335 			guid = (e_guid_t *)fvalue_get(&fi->value);
9336 			tmp = guid_to_str(NULL, guid);
9337 			label_fill(label_str, 0, hfinfo, tmp);
9338 			wmem_free(NULL, tmp);
9339 			break;
9340 
9341 		case FT_OID:
9342 			bytes = (guint8 *)fvalue_get(&fi->value);
9343 			name = oid_resolved_from_encoded(NULL, bytes, fvalue_length(&fi->value));
9344 			tmp = oid_encoded2string(NULL, bytes, fvalue_length(&fi->value));
9345 			if (name) {
9346 				label_fill_descr(label_str, 0, hfinfo, tmp, name);
9347 				wmem_free(NULL, name);
9348 			} else {
9349 				label_fill(label_str, 0, hfinfo, tmp);
9350 			}
9351 			wmem_free(NULL, tmp);
9352 			break;
9353 
9354 		case FT_REL_OID:
9355 			bytes = (guint8 *)fvalue_get(&fi->value);
9356 			name = rel_oid_resolved_from_encoded(NULL, bytes, fvalue_length(&fi->value));
9357 			tmp = rel_oid_encoded2string(NULL, bytes, fvalue_length(&fi->value));
9358 			if (name) {
9359 				label_fill_descr(label_str, 0, hfinfo, tmp, name);
9360 				wmem_free(NULL, name);
9361 			} else {
9362 				label_fill(label_str, 0, hfinfo, tmp);
9363 			}
9364 			wmem_free(NULL, tmp);
9365 			break;
9366 
9367 		case FT_SYSTEM_ID:
9368 			bytes = (guint8 *)fvalue_get(&fi->value);
9369 			tmp = print_system_id(NULL, bytes, fvalue_length(&fi->value));
9370 			label_fill(label_str, 0, hfinfo, tmp);
9371 			wmem_free(NULL, tmp);
9372 			break;
9373 
9374 		case FT_EUI64:
9375 			integer64 = fvalue_get_uinteger64(&fi->value);
9376 			addr_str = eui64_to_str(NULL, integer64);
9377 			tmp = (char*)eui64_to_display(NULL, integer64);
9378 			label_fill_descr(label_str, 0, hfinfo, tmp, addr_str);
9379 			wmem_free(NULL, tmp);
9380 			wmem_free(NULL, addr_str);
9381 			break;
9382 		case FT_STRING:
9383 		case FT_STRINGZ:
9384 		case FT_UINT_STRING:
9385 		case FT_STRINGZPAD:
9386 		case FT_STRINGZTRUNC:
9387 			bytes = (guint8 *)fvalue_get(&fi->value);
9388 			tmp = hfinfo_format_text(NULL, hfinfo, bytes);
9389 			label_fill(label_str, 0, hfinfo, tmp);
9390 			wmem_free(NULL, tmp);
9391 			break;
9392 
9393 		case FT_IEEE_11073_SFLOAT:
9394 		case FT_IEEE_11073_FLOAT:
9395 			tmp = fvalue_to_string_repr(NULL, &fi->value, FTREPR_DISPLAY, hfinfo->display);
9396 			g_snprintf(label_str, ITEM_LABEL_LENGTH,
9397 						"%s: %s",
9398 						hfinfo->name, tmp);
9399 			wmem_free(NULL, tmp);
9400 			break;
9401 
9402 		default:
9403 			REPORT_DISSECTOR_BUG("field %s has type %d (%s) not handled in proto_item_fill_label()",
9404 					     hfinfo->abbrev,
9405 					     hfinfo->type,
9406 					     ftype_name(hfinfo->type));
9407 			break;
9408 	}
9409 }
9410 
9411 static void
fill_label_boolean(field_info * fi,gchar * label_str)9412 fill_label_boolean(field_info *fi, gchar *label_str)
9413 {
9414 	char	*p                    = label_str;
9415 	int      bitfield_byte_length = 0, bitwidth;
9416 	guint64  unshifted_value;
9417 	guint64  value;
9418 
9419 	header_field_info	*hfinfo   = fi->hfinfo;
9420 	const true_false_string	*tfstring = &tfs_true_false;
9421 
9422 	if (hfinfo->strings) {
9423 		tfstring = (const struct true_false_string*) hfinfo->strings;
9424 	}
9425 
9426 	value = fvalue_get_uinteger64(&fi->value);
9427 	if (hfinfo->bitmask) {
9428 		/* Figure out the bit width */
9429 		bitwidth = hfinfo_container_bitwidth(hfinfo);
9430 
9431 		/* Un-shift bits */
9432 		unshifted_value = value;
9433 		unshifted_value <<= hfinfo_bitshift(hfinfo);
9434 
9435 		/* Create the bitfield first */
9436 		p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
9437 		bitfield_byte_length = (int) (p - label_str);
9438 	}
9439 
9440 	/* Fill in the textual info */
9441 	label_fill(label_str, bitfield_byte_length, hfinfo, tfs_get_string(!!value, tfstring));
9442 }
9443 
9444 static const char *
hf_try_val_to_str(guint32 value,const header_field_info * hfinfo)9445 hf_try_val_to_str(guint32 value, const header_field_info *hfinfo)
9446 {
9447 	if (hfinfo->display & BASE_RANGE_STRING)
9448 		return try_rval_to_str(value, (const range_string *) hfinfo->strings);
9449 
9450 	if (hfinfo->display & BASE_EXT_STRING) {
9451 		if (hfinfo->display & BASE_VAL64_STRING)
9452 			return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
9453 		else
9454 			return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
9455 	}
9456 
9457 	if (hfinfo->display & BASE_VAL64_STRING)
9458 		return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
9459 
9460 	if (hfinfo->display & BASE_UNIT_STRING)
9461 		return unit_name_string_get_value(value, (const struct unit_name_string*) hfinfo->strings);
9462 
9463 	return try_val_to_str(value, (const value_string *) hfinfo->strings);
9464 }
9465 
9466 static const char *
hf_try_val64_to_str(guint64 value,const header_field_info * hfinfo)9467 hf_try_val64_to_str(guint64 value, const header_field_info *hfinfo)
9468 {
9469 	if (hfinfo->display & BASE_VAL64_STRING) {
9470 		if (hfinfo->display & BASE_EXT_STRING)
9471 			return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
9472 		else
9473 			return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
9474 	}
9475 
9476 	if (hfinfo->display & BASE_RANGE_STRING)
9477 		return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
9478 
9479 	if (hfinfo->display & BASE_UNIT_STRING)
9480 		return unit_name_string_get_value64(value, (const struct unit_name_string*) hfinfo->strings);
9481 
9482 	/* If this is reached somebody registered a 64-bit field with a 32-bit
9483 	 * value-string, which isn't right. */
9484 	REPORT_DISSECTOR_BUG("field %s is a 64-bit field with a 32-bit value_string",
9485 	    hfinfo->abbrev);
9486 
9487 	/* This is necessary to squelch MSVC errors; is there
9488 	   any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
9489 	   never returns? */
9490 	return NULL;
9491 }
9492 
9493 static const char *
hf_try_val_to_str_const(guint32 value,const header_field_info * hfinfo,const char * unknown_str)9494 hf_try_val_to_str_const(guint32 value, const header_field_info *hfinfo, const char *unknown_str)
9495 {
9496 	const char *str = hf_try_val_to_str(value, hfinfo);
9497 
9498 	return (str) ? str : unknown_str;
9499 }
9500 
9501 static const char *
hf_try_val64_to_str_const(guint64 value,const header_field_info * hfinfo,const char * unknown_str)9502 hf_try_val64_to_str_const(guint64 value, const header_field_info *hfinfo, const char *unknown_str)
9503 {
9504 	const char *str = hf_try_val64_to_str(value, hfinfo);
9505 
9506 	return (str) ? str : unknown_str;
9507 }
9508 
9509 /* Fills data for bitfield chars with val_strings */
9510 static void
fill_label_bitfield_char(field_info * fi,gchar * label_str)9511 fill_label_bitfield_char(field_info *fi, gchar *label_str)
9512 {
9513 	char       *p;
9514 	int         bitfield_byte_length, bitwidth;
9515 	guint32     unshifted_value;
9516 	guint32     value;
9517 
9518 	char        buf[32];
9519 	const char *out;
9520 
9521 	header_field_info *hfinfo = fi->hfinfo;
9522 
9523 	/* Figure out the bit width */
9524 	bitwidth = hfinfo_container_bitwidth(hfinfo);
9525 
9526 	/* Un-shift bits */
9527 	value = fvalue_get_uinteger(&fi->value);
9528 
9529 	unshifted_value = value;
9530 	if (hfinfo->bitmask) {
9531 		unshifted_value <<= hfinfo_bitshift(hfinfo);
9532 	}
9533 
9534 	/* Create the bitfield first */
9535 	p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
9536 	bitfield_byte_length = (int) (p - label_str);
9537 
9538 	/* Fill in the textual info using stored (shifted) value */
9539 	if (hfinfo->display == BASE_CUSTOM) {
9540 		gchar tmp[ITEM_LABEL_LENGTH];
9541 		const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
9542 
9543 		DISSECTOR_ASSERT(fmtfunc);
9544 		fmtfunc(tmp, value);
9545 		label_fill(label_str, bitfield_byte_length, hfinfo, tmp);
9546 	}
9547 	else if (hfinfo->strings) {
9548 		const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
9549 
9550 		out = hfinfo_char_vals_format(hfinfo, buf, value);
9551 		if (out == NULL) /* BASE_NONE so don't put integer in descr */
9552 			label_fill(label_str, bitfield_byte_length, hfinfo, val_str);
9553 		else
9554 			label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out);
9555 	}
9556 	else {
9557 		out = hfinfo_char_value_format(hfinfo, buf, value);
9558 
9559 		label_fill(label_str, bitfield_byte_length, hfinfo, out);
9560 	}
9561 }
9562 
9563 /* Fills data for bitfield ints with val_strings */
9564 static void
fill_label_bitfield(field_info * fi,gchar * label_str,gboolean is_signed)9565 fill_label_bitfield(field_info *fi, gchar *label_str, gboolean is_signed)
9566 {
9567 	char       *p;
9568 	int         bitfield_byte_length, bitwidth;
9569 	guint32     unshifted_value;
9570 	guint32     value;
9571 
9572 	char        buf[32];
9573 	const char *out;
9574 
9575 	header_field_info *hfinfo = fi->hfinfo;
9576 
9577 	/* Figure out the bit width */
9578 	bitwidth = hfinfo_container_bitwidth(hfinfo);
9579 
9580 	/* Un-shift bits */
9581 	if (is_signed)
9582 		value = fvalue_get_sinteger(&fi->value);
9583 	else
9584 		value = fvalue_get_uinteger(&fi->value);
9585 
9586 	unshifted_value = value;
9587 	if (hfinfo->bitmask) {
9588 		unshifted_value <<= hfinfo_bitshift(hfinfo);
9589 	}
9590 
9591 	/* Create the bitfield first */
9592 	p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
9593 	bitfield_byte_length = (int) (p - label_str);
9594 
9595 	/* Fill in the textual info using stored (shifted) value */
9596 	if (hfinfo->display == BASE_CUSTOM) {
9597 		gchar tmp[ITEM_LABEL_LENGTH];
9598 		const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
9599 
9600 		DISSECTOR_ASSERT(fmtfunc);
9601 		fmtfunc(tmp, value);
9602 		label_fill(label_str, bitfield_byte_length, hfinfo, tmp);
9603 	}
9604 	else if (hfinfo->strings) {
9605 		const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
9606 
9607 		out = hfinfo_number_vals_format(hfinfo, buf, value);
9608 		if (out == NULL) /* BASE_NONE so don't put integer in descr */
9609 			label_fill(label_str, bitfield_byte_length, hfinfo, val_str);
9610 		else
9611 			label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out);
9612 	}
9613 	else {
9614 		out = hfinfo_number_value_format(hfinfo, buf, value);
9615 
9616 		label_fill(label_str, bitfield_byte_length, hfinfo, out);
9617 	}
9618 }
9619 
9620 static void
fill_label_bitfield64(field_info * fi,gchar * label_str,gboolean is_signed)9621 fill_label_bitfield64(field_info *fi, gchar *label_str, gboolean is_signed)
9622 {
9623 	char       *p;
9624 	int         bitfield_byte_length, bitwidth;
9625 	guint64     unshifted_value;
9626 	guint64     value;
9627 
9628 	char        buf[48];
9629 	const char *out;
9630 
9631 	header_field_info *hfinfo = fi->hfinfo;
9632 
9633 	/* Figure out the bit width */
9634 	bitwidth = hfinfo_container_bitwidth(hfinfo);
9635 
9636 	/* Un-shift bits */
9637 	if (is_signed)
9638 		value = fvalue_get_sinteger64(&fi->value);
9639 	else
9640 		value = fvalue_get_uinteger64(&fi->value);
9641 
9642 	unshifted_value = value;
9643 	if (hfinfo->bitmask) {
9644 		unshifted_value <<= hfinfo_bitshift(hfinfo);
9645 	}
9646 
9647 	/* Create the bitfield first */
9648 	p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
9649 	bitfield_byte_length = (int) (p - label_str);
9650 
9651 	/* Fill in the textual info using stored (shifted) value */
9652 	if (hfinfo->display == BASE_CUSTOM) {
9653 		gchar tmp[ITEM_LABEL_LENGTH];
9654 		const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
9655 
9656 		DISSECTOR_ASSERT(fmtfunc64);
9657 		fmtfunc64(tmp, value);
9658 		label_fill(label_str, bitfield_byte_length, hfinfo, tmp);
9659 	}
9660 	else if (hfinfo->strings) {
9661 		const char *val_str = hf_try_val64_to_str_const(value, hfinfo, "Unknown");
9662 
9663 		out = hfinfo_number_vals_format64(hfinfo, buf, value);
9664 		if (out == NULL) /* BASE_NONE so don't put integer in descr */
9665 			label_fill(label_str, bitfield_byte_length, hfinfo, val_str);
9666 		else
9667 			label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out);
9668 	}
9669 	else {
9670 		out = hfinfo_number_value_format64(hfinfo, buf, value);
9671 
9672 		label_fill(label_str, bitfield_byte_length, hfinfo, out);
9673 	}
9674 }
9675 
9676 static void
fill_label_bitfield_varint(field_info * fi,gchar * label_str,gboolean is_signed)9677 fill_label_bitfield_varint(field_info *fi, gchar *label_str, gboolean is_signed)
9678 {
9679 	char       *p;
9680 	int         bitfield_byte_length;
9681 	guint32     value, unshifted_value;
9682 	char        buf[48];
9683 	const char *out;
9684 
9685 	header_field_info *hfinfo = fi->hfinfo;
9686 
9687 	/* Un-shift bits */
9688 	if (is_signed) {
9689 		value = fvalue_get_sinteger(&fi->value);
9690 	} else {
9691 		value = fvalue_get_uinteger(&fi->value);
9692 	}
9693 	unshifted_value = value;
9694 	if (hfinfo->bitmask) {
9695 		unshifted_value <<= hfinfo_bitshift(hfinfo);
9696 	}
9697 
9698 	/* Create the bitfield first */
9699 	p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, fi->length*8);
9700 	bitfield_byte_length = (int) (p - label_str);
9701 
9702 	/* Fill in the textual info using stored (shifted) value */
9703 	if (hfinfo->display == BASE_CUSTOM) {
9704 		gchar tmp[ITEM_LABEL_LENGTH];
9705 		const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
9706 
9707 		DISSECTOR_ASSERT(fmtfunc);
9708 		fmtfunc(tmp, value);
9709 		label_fill(label_str, bitfield_byte_length, hfinfo, tmp);
9710 	}
9711 	else if (hfinfo->strings) {
9712 		const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
9713 
9714 		out = hfinfo_number_vals_format(hfinfo, buf, value);
9715 		if (out == NULL) /* BASE_NONE so don't put integer in descr */
9716 			label_fill(label_str, bitfield_byte_length, hfinfo, val_str);
9717 		else
9718 			label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out);
9719 	}
9720 	else {
9721 		out = hfinfo_number_value_format(hfinfo, buf, value);
9722 
9723 		label_fill(label_str, bitfield_byte_length, hfinfo, out);
9724 	}
9725 }
9726 
9727 static void
fill_label_bitfield_varint64(field_info * fi,gchar * label_str,gboolean is_signed)9728 fill_label_bitfield_varint64(field_info *fi, gchar *label_str, gboolean is_signed)
9729 {
9730 	char       *p;
9731 	int         bitfield_byte_length;
9732 	guint64     unshifted_value;
9733 	guint64     value;
9734 
9735 	char        buf[48];
9736 	const char *out;
9737 
9738 	header_field_info *hfinfo = fi->hfinfo;
9739 
9740 	/* Un-shift bits */
9741 	if (is_signed) {
9742 		value = fvalue_get_sinteger64(&fi->value);
9743 	} else {
9744 		value = fvalue_get_uinteger64(&fi->value);
9745 	}
9746 	unshifted_value = value;
9747 	if (hfinfo->bitmask) {
9748 		unshifted_value <<= hfinfo_bitshift(hfinfo);
9749 	}
9750 
9751 	/* Create the bitfield first */
9752 	p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, fi->length*8);
9753 	bitfield_byte_length = (int) (p - label_str);
9754 
9755 	/* Fill in the textual info using stored (shifted) value */
9756 	if (hfinfo->display == BASE_CUSTOM) {
9757 		gchar tmp[ITEM_LABEL_LENGTH];
9758 		const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
9759 
9760 		DISSECTOR_ASSERT(fmtfunc64);
9761 		fmtfunc64(tmp, value);
9762 		label_fill(label_str, bitfield_byte_length, hfinfo, tmp);
9763 	}
9764 	else if (hfinfo->strings) {
9765 		const char *val_str = hf_try_val64_to_str_const(value, hfinfo, "Unknown");
9766 
9767 		out = hfinfo_number_vals_format64(hfinfo, buf, value);
9768 		if (out == NULL) /* BASE_NONE so don't put integer in descr */
9769 			label_fill(label_str, bitfield_byte_length, hfinfo, val_str);
9770 		else
9771 			label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out);
9772 	}
9773 	else {
9774 		out = hfinfo_number_value_format64(hfinfo, buf, value);
9775 
9776 		label_fill(label_str, bitfield_byte_length, hfinfo, out);
9777 	}
9778 }
9779 
9780 static void
fill_label_char(field_info * fi,gchar * label_str)9781 fill_label_char(field_info *fi, gchar *label_str)
9782 {
9783 	header_field_info *hfinfo = fi->hfinfo;
9784 	guint32            value;
9785 
9786 	char               buf[32];
9787 	const char        *out;
9788 
9789 	value = fvalue_get_uinteger(&fi->value);
9790 
9791 	/* Fill in the textual info */
9792 	if (hfinfo->display == BASE_CUSTOM) {
9793 		gchar tmp[ITEM_LABEL_LENGTH];
9794 		const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
9795 
9796 		DISSECTOR_ASSERT(fmtfunc);
9797 		fmtfunc(tmp, value);
9798 		label_fill(label_str, 0, hfinfo, tmp);
9799 	}
9800 	else if (hfinfo->strings) {
9801 		const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
9802 
9803 		out = hfinfo_char_vals_format(hfinfo, buf, value);
9804 		label_fill_descr(label_str, 0, hfinfo, val_str, out);
9805 	}
9806 	else {
9807 		out = hfinfo_char_value_format(hfinfo, buf, value);
9808 
9809 		label_fill(label_str, 0, hfinfo, out);
9810 	}
9811 }
9812 
9813 static void
fill_label_number(field_info * fi,gchar * label_str,gboolean is_signed)9814 fill_label_number(field_info *fi, gchar *label_str, gboolean is_signed)
9815 {
9816 	header_field_info *hfinfo = fi->hfinfo;
9817 	guint32            value;
9818 
9819 	char               buf[32];
9820 	const char        *out;
9821 
9822 	if (is_signed)
9823 		value = fvalue_get_sinteger(&fi->value);
9824 	else
9825 		value = fvalue_get_uinteger(&fi->value);
9826 
9827 	/* Fill in the textual info */
9828 	if (hfinfo->display == BASE_CUSTOM) {
9829 		gchar tmp[ITEM_LABEL_LENGTH];
9830 		const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
9831 
9832 		DISSECTOR_ASSERT(fmtfunc);
9833 		fmtfunc(tmp, value);
9834 		label_fill(label_str, 0, hfinfo, tmp);
9835 	}
9836 	else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
9837 		/*
9838 		 * It makes no sense to have a value-string table for a
9839 		 * frame-number field - they're just integers giving
9840 		 * the ordinal frame number.
9841 		 */
9842 		const char *val_str = hf_try_val_to_str(value, hfinfo);
9843 
9844 		out = hfinfo_number_vals_format(hfinfo, buf, value);
9845 		if (hfinfo->display & BASE_SPECIAL_VALS) {
9846 			/*
9847 			 * Unique values only display value_string string
9848 			 * if there is a match. Otherwise it's just a number
9849 			 */
9850 			if (val_str) {
9851 				label_fill_descr(label_str, 0, hfinfo, val_str, out);
9852 			} else {
9853 				label_fill(label_str, 0, hfinfo, out);
9854 			}
9855 		} else {
9856 			if (val_str == NULL)
9857 				val_str = "Unknown";
9858 
9859 			if (out == NULL) /* BASE_NONE so don't put integer in descr */
9860 				label_fill(label_str, 0, hfinfo, val_str);
9861 			else
9862 				label_fill_descr(label_str, 0, hfinfo, val_str, out);
9863 		}
9864 	}
9865 	else if (IS_BASE_PORT(hfinfo->display)) {
9866 		gchar tmp[ITEM_LABEL_LENGTH];
9867 
9868 		port_with_resolution_to_str_buf(tmp, sizeof(tmp),
9869 			display_to_port_type((field_display_e)hfinfo->display), value);
9870 		label_fill(label_str, 0, hfinfo, tmp);
9871 	}
9872 	else {
9873 		out = hfinfo_number_value_format(hfinfo, buf, value);
9874 
9875 		label_fill(label_str, 0, hfinfo, out);
9876 	}
9877 }
9878 
9879 static void
fill_label_number64(field_info * fi,gchar * label_str,gboolean is_signed)9880 fill_label_number64(field_info *fi, gchar *label_str, gboolean is_signed)
9881 {
9882 	header_field_info *hfinfo = fi->hfinfo;
9883 	guint64            value;
9884 
9885 	char               buf[48];
9886 	const char        *out;
9887 
9888 	if (is_signed)
9889 		value = fvalue_get_sinteger64(&fi->value);
9890 	else
9891 		value = fvalue_get_uinteger64(&fi->value);
9892 
9893 	/* Fill in the textual info */
9894 	if (hfinfo->display == BASE_CUSTOM) {
9895 		gchar tmp[ITEM_LABEL_LENGTH];
9896 		const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
9897 
9898 		DISSECTOR_ASSERT(fmtfunc64);
9899 		fmtfunc64(tmp, value);
9900 		label_fill(label_str, 0, hfinfo, tmp);
9901 	}
9902 	else if (hfinfo->strings) {
9903 		const char *val_str = hf_try_val64_to_str(value, hfinfo);
9904 
9905 		out = hfinfo_number_vals_format64(hfinfo, buf, value);
9906 		if (hfinfo->display & BASE_SPECIAL_VALS) {
9907 			/*
9908 			 * Unique values only display value_string string
9909 			 * if there is a match. Otherwise it's just a number
9910 			 */
9911 			if (val_str) {
9912 				label_fill_descr(label_str, 0, hfinfo, val_str, out);
9913 			} else {
9914 				label_fill(label_str, 0, hfinfo, out);
9915 			}
9916 		} else {
9917 			if (val_str == NULL)
9918 				val_str = "Unknown";
9919 
9920 			if (out == NULL) /* BASE_NONE so don't put integer in descr */
9921 				label_fill(label_str, 0, hfinfo, val_str);
9922 			else
9923 				label_fill_descr(label_str, 0, hfinfo, val_str, out);
9924 		}
9925 	}
9926 	else {
9927 		out = hfinfo_number_value_format64(hfinfo, buf, value);
9928 
9929 		label_fill(label_str, 0, hfinfo, out);
9930 	}
9931 }
9932 
9933 int
hfinfo_bitshift(const header_field_info * hfinfo)9934 hfinfo_bitshift(const header_field_info *hfinfo)
9935 {
9936 	return ws_ctz(hfinfo->bitmask);
9937 }
9938 
9939 
9940 static int
hfinfo_bitoffset(const header_field_info * hfinfo)9941 hfinfo_bitoffset(const header_field_info *hfinfo)
9942 {
9943 	if (!hfinfo->bitmask) {
9944 		return 0;
9945 	}
9946 
9947 	/* ilog2 = first set bit, counting 0 as the last bit; we want 0
9948 	 * as the first bit */
9949 	return hfinfo_container_bitwidth(hfinfo) - 1 - ws_ilog2(hfinfo->bitmask);
9950 }
9951 
9952 static int
hfinfo_mask_bitwidth(const header_field_info * hfinfo)9953 hfinfo_mask_bitwidth(const header_field_info *hfinfo)
9954 {
9955 	if (!hfinfo->bitmask) {
9956 		return 0;
9957 	}
9958 
9959 	/* ilog2 = first set bit, ctz = last set bit */
9960 	return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
9961 }
9962 
9963 static int
hfinfo_type_bitwidth(enum ftenum type)9964 hfinfo_type_bitwidth(enum ftenum type)
9965 {
9966 	int bitwidth = 0;
9967 
9968 	switch (type) {
9969 		case FT_CHAR:
9970 		case FT_UINT8:
9971 		case FT_INT8:
9972 			bitwidth = 8;
9973 			break;
9974 		case FT_UINT16:
9975 		case FT_INT16:
9976 			bitwidth = 16;
9977 			break;
9978 		case FT_UINT24:
9979 		case FT_INT24:
9980 			bitwidth = 24;
9981 			break;
9982 		case FT_UINT32:
9983 		case FT_INT32:
9984 			bitwidth = 32;
9985 			break;
9986 		case FT_UINT40:
9987 		case FT_INT40:
9988 			bitwidth = 40;
9989 			break;
9990 		case FT_UINT48:
9991 		case FT_INT48:
9992 			bitwidth = 48;
9993 			break;
9994 		case FT_UINT56:
9995 		case FT_INT56:
9996 			bitwidth = 56;
9997 			break;
9998 		case FT_UINT64:
9999 		case FT_INT64:
10000 			bitwidth = 64;
10001 			break;
10002 		default:
10003 			DISSECTOR_ASSERT_NOT_REACHED();
10004 			;
10005 	}
10006 	return bitwidth;
10007 }
10008 
10009 
10010 static int
hfinfo_container_bitwidth(const header_field_info * hfinfo)10011 hfinfo_container_bitwidth(const header_field_info *hfinfo)
10012 {
10013 	if (!hfinfo->bitmask) {
10014 		return 0;
10015 	}
10016 
10017 	if (hfinfo->type == FT_BOOLEAN) {
10018 		return hfinfo->display; /* hacky? :) */
10019 	}
10020 
10021 	return hfinfo_type_bitwidth(hfinfo->type);
10022 }
10023 
10024 static int
hfinfo_hex_digits(const header_field_info * hfinfo)10025 hfinfo_hex_digits(const header_field_info *hfinfo)
10026 {
10027 	int bitwidth;
10028 
10029 	/* If we have a bitmask, hfinfo->type is the width of the container, so not
10030 	 * appropriate to determine the number of hex digits for the field.
10031 	 * So instead, we compute it from the bitmask.
10032 	 */
10033 	if (hfinfo->bitmask != 0) {
10034 		bitwidth = hfinfo_mask_bitwidth(hfinfo);
10035 	} else {
10036 		bitwidth = hfinfo_type_bitwidth(hfinfo->type);
10037 	}
10038 
10039 	/* Divide by 4, rounding up, to get number of hex digits. */
10040 	return (bitwidth + 3) / 4;
10041 }
10042 
10043 static const char *
hfinfo_char_value_format_display(int display,char buf[7],guint32 value)10044 hfinfo_char_value_format_display(int display, char buf[7], guint32 value)
10045 {
10046 	char *ptr = &buf[6];
10047 	static const gchar hex_digits[16] =
10048 	{ '0', '1', '2', '3', '4', '5', '6', '7',
10049 	  '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
10050 
10051 	*ptr = '\0';
10052 	*(--ptr) = '\'';
10053 	/* Properly format value */
10054 	if (g_ascii_isprint(value)) {
10055 		/*
10056 		 * Printable, so just show the character, and, if it needs
10057 		 * to be escaped, escape it.
10058 		 */
10059 		*(--ptr) = value;
10060 		if (value == '\\' || value == '\'')
10061 			*(--ptr) = '\\';
10062 	} else {
10063 		/*
10064 		 * Non-printable; show it as an escape sequence.
10065 		 */
10066 		switch (value) {
10067 
10068 		case '\0':
10069 			/*
10070 			 * Show a NUL with only one digit.
10071 			 */
10072 			*(--ptr) = '0';
10073 			break;
10074 
10075 		case '\a':
10076 			*(--ptr) = 'a';
10077 			break;
10078 
10079 		case '\b':
10080 			*(--ptr) = 'b';
10081 			break;
10082 
10083 		case '\f':
10084 			*(--ptr) = 'f';
10085 			break;
10086 
10087 		case '\n':
10088 			*(--ptr) = 'n';
10089 			break;
10090 
10091 		case '\r':
10092 			*(--ptr) = 'r';
10093 			break;
10094 
10095 		case '\t':
10096 			*(--ptr) = 't';
10097 			break;
10098 
10099 		case '\v':
10100 			*(--ptr) = 'v';
10101 			break;
10102 
10103 		default:
10104 			switch (FIELD_DISPLAY(display)) {
10105 
10106 			case BASE_OCT:
10107 				*(--ptr) = (value & 0x7) + '0';
10108 				value >>= 3;
10109 				*(--ptr) = (value & 0x7) + '0';
10110 				value >>= 3;
10111 				*(--ptr) = (value & 0x7) + '0';
10112 				break;
10113 
10114 			case BASE_HEX:
10115 				*(--ptr) = hex_digits[value & 0x0F];
10116 				value >>= 4;
10117 				*(--ptr) = hex_digits[value & 0x0F];
10118 				*(--ptr) = 'x';
10119 				break;
10120 
10121 			default:
10122 				REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display));
10123 			}
10124 		}
10125 		*(--ptr) = '\\';
10126 	}
10127 	*(--ptr) = '\'';
10128 	return ptr;
10129 }
10130 
10131 static const char *
hfinfo_number_value_format_display(const header_field_info * hfinfo,int display,char buf[32],guint32 value)10132 hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[32], guint32 value)
10133 {
10134 	char *ptr = &buf[31];
10135 	gboolean isint = IS_FT_INT(hfinfo->type);
10136 
10137 	*ptr = '\0';
10138 	/* Properly format value */
10139 	switch (FIELD_DISPLAY(display)) {
10140 		case BASE_DEC:
10141 			return isint ? int_to_str_back(ptr, (gint32) value) : uint_to_str_back(ptr, value);
10142 
10143 		case BASE_DEC_HEX:
10144 			*(--ptr) = ')';
10145 			ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
10146 			*(--ptr) = '(';
10147 			*(--ptr) = ' ';
10148 			ptr = isint ? int_to_str_back(ptr, (gint32) value) : uint_to_str_back(ptr, value);
10149 			return ptr;
10150 
10151 		case BASE_OCT:
10152 			return oct_to_str_back(ptr, value);
10153 
10154 		case BASE_HEX:
10155 			return hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
10156 
10157 		case BASE_HEX_DEC:
10158 			*(--ptr) = ')';
10159 			ptr = isint ? int_to_str_back(ptr, (gint32) value) : uint_to_str_back(ptr, value);
10160 			*(--ptr) = '(';
10161 			*(--ptr) = ' ';
10162 			ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
10163 			return ptr;
10164 
10165 		case BASE_PT_UDP:
10166 		case BASE_PT_TCP:
10167 		case BASE_PT_DCCP:
10168 		case BASE_PT_SCTP:
10169 			port_with_resolution_to_str_buf(buf, 32,
10170 					display_to_port_type((field_display_e)display), value);
10171 			return buf;
10172 		case BASE_OUI:
10173 			{
10174 			guint8 p_oui[3];
10175 			const gchar *manuf_name;
10176 
10177 			p_oui[0] = value >> 16 & 0xFF;
10178 			p_oui[1] = value >> 8 & 0xFF;
10179 			p_oui[2] = value & 0xFF;
10180 
10181 			/* Attempt an OUI lookup. */
10182 			manuf_name = uint_get_manuf_name_if_known(value);
10183 			if (manuf_name == NULL) {
10184 				/* Could not find an OUI. */
10185 				g_snprintf(buf, 32, "%02x:%02x:%02x", p_oui[0], p_oui[1], p_oui[2]);
10186 			}
10187 			else {
10188 				/* Found an address string. */
10189 				g_snprintf(buf, 32, "%02x:%02x:%02x (%s)", p_oui[0], p_oui[1], p_oui[2], manuf_name);
10190 			}
10191 			return buf;
10192 			}
10193 
10194 		default:
10195 			REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display));
10196 	}
10197 	return ptr;
10198 }
10199 
10200 static const char *
hfinfo_number_value_format_display64(const header_field_info * hfinfo,int display,char buf[48],guint64 value)10201 hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[48], guint64 value)
10202 {
10203 	char *ptr = &buf[47];
10204 	gboolean isint = IS_FT_INT(hfinfo->type);
10205 
10206 	*ptr = '\0';
10207 	/* Properly format value */
10208 	switch (FIELD_DISPLAY(display)) {
10209 		case BASE_DEC:
10210 			return isint ? int64_to_str_back(ptr, (gint64) value) : uint64_to_str_back(ptr, value);
10211 
10212 		case BASE_DEC_HEX:
10213 			*(--ptr) = ')';
10214 			ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
10215 			*(--ptr) = '(';
10216 			*(--ptr) = ' ';
10217 			ptr = isint ? int64_to_str_back(ptr, (gint64) value) : uint64_to_str_back(ptr, value);
10218 			return ptr;
10219 
10220 		case BASE_OCT:
10221 			return oct64_to_str_back(ptr, value);
10222 
10223 		case BASE_HEX:
10224 			return hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
10225 
10226 		case BASE_HEX_DEC:
10227 			*(--ptr) = ')';
10228 			ptr = isint ? int64_to_str_back(ptr, (gint64) value) : uint64_to_str_back(ptr, value);
10229 			*(--ptr) = '(';
10230 			*(--ptr) = ' ';
10231 			ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
10232 			return ptr;
10233 
10234 		default:
10235 			REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display));
10236 	}
10237 
10238 	return ptr;
10239 }
10240 
10241 static const char *
hfinfo_number_value_format(const header_field_info * hfinfo,char buf[32],guint32 value)10242 hfinfo_number_value_format(const header_field_info *hfinfo, char buf[32], guint32 value)
10243 {
10244 	int display = hfinfo->display;
10245 
10246 	if (hfinfo->type == FT_FRAMENUM) {
10247 		/*
10248 		 * Frame numbers are always displayed in decimal.
10249 		 */
10250 		display = BASE_DEC;
10251 	}
10252 
10253 	return hfinfo_number_value_format_display(hfinfo, display, buf, value);
10254 }
10255 
10256 static const char *
hfinfo_number_value_format64(const header_field_info * hfinfo,char buf[48],guint64 value)10257 hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[48], guint64 value)
10258 {
10259 	int display = hfinfo->display;
10260 
10261 	if (hfinfo->type == FT_FRAMENUM) {
10262 		/*
10263 		 * Frame numbers are always displayed in decimal.
10264 		 */
10265 		display = BASE_DEC;
10266 	}
10267 
10268 	return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
10269 }
10270 
10271 static const char *
hfinfo_char_value_format(const header_field_info * hfinfo,char buf[32],guint32 value)10272 hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], guint32 value)
10273 {
10274 	/* Get the underlying BASE_ value */
10275 	int display = FIELD_DISPLAY(hfinfo->display);
10276 
10277 	return hfinfo_char_value_format_display(display, buf, value);
10278 }
10279 
10280 static const char *
hfinfo_numeric_value_format(const header_field_info * hfinfo,char buf[32],guint32 value)10281 hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[32], guint32 value)
10282 {
10283 	/* Get the underlying BASE_ value */
10284 	int display = FIELD_DISPLAY(hfinfo->display);
10285 
10286 	if (hfinfo->type == FT_FRAMENUM) {
10287 		/*
10288 		 * Frame numbers are always displayed in decimal.
10289 		 */
10290 		display = BASE_DEC;
10291 	}
10292 
10293 	if (IS_BASE_PORT(display)) {
10294 		display = BASE_DEC;
10295 	} else if (display == BASE_OUI) {
10296 		display = BASE_HEX;
10297 	}
10298 
10299 	switch (display) {
10300 		case BASE_NONE:
10301 		/* case BASE_DEC: */
10302 		case BASE_DEC_HEX:
10303 		case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
10304 		case BASE_CUSTOM:
10305 			display = BASE_DEC;
10306 			break;
10307 
10308 		/* case BASE_HEX: */
10309 		case BASE_HEX_DEC:
10310 			display = BASE_HEX;
10311 			break;
10312 	}
10313 
10314 	return hfinfo_number_value_format_display(hfinfo, display, buf, value);
10315 }
10316 
10317 static const char *
hfinfo_numeric_value_format64(const header_field_info * hfinfo,char buf[48],guint64 value)10318 hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[48], guint64 value)
10319 {
10320 	/* Get the underlying BASE_ value */
10321 	int display = FIELD_DISPLAY(hfinfo->display);
10322 
10323 	if (hfinfo->type == FT_FRAMENUM) {
10324 		/*
10325 		 * Frame numbers are always displayed in decimal.
10326 		 */
10327 		display = BASE_DEC;
10328 	}
10329 
10330 	switch (display) {
10331 		case BASE_NONE:
10332 		/* case BASE_DEC: */
10333 		case BASE_DEC_HEX:
10334 		case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
10335 		case BASE_CUSTOM:
10336 			display = BASE_DEC;
10337 			break;
10338 
10339 		/* case BASE_HEX: */
10340 		case BASE_HEX_DEC:
10341 			display = BASE_HEX;
10342 			break;
10343 	}
10344 
10345 	return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
10346 }
10347 
10348 static const char *
hfinfo_char_vals_format(const header_field_info * hfinfo,char buf[32],guint32 value)10349 hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value)
10350 {
10351 	/* Get the underlying BASE_ value */
10352 	int display = FIELD_DISPLAY(hfinfo->display);
10353 
10354 	return hfinfo_char_value_format_display(display, buf, value);
10355 }
10356 
10357 static const char *
hfinfo_number_vals_format(const header_field_info * hfinfo,char buf[32],guint32 value)10358 hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value)
10359 {
10360 	/* Get the underlying BASE_ value */
10361 	int display = FIELD_DISPLAY(hfinfo->display);
10362 
10363 	if (display == BASE_NONE)
10364 		return NULL;
10365 
10366 	if (display == BASE_DEC_HEX)
10367 		display = BASE_DEC;
10368 	if (display == BASE_HEX_DEC)
10369 		display = BASE_HEX;
10370 
10371 	return hfinfo_number_value_format_display(hfinfo, display, buf, value);
10372 }
10373 
10374 static const char *
hfinfo_number_vals_format64(const header_field_info * hfinfo,char buf[48],guint64 value)10375 hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[48], guint64 value)
10376 {
10377 	/* Get the underlying BASE_ value */
10378 	int display = FIELD_DISPLAY(hfinfo->display);
10379 
10380 	if (display == BASE_NONE)
10381 		return NULL;
10382 
10383 	if (display == BASE_DEC_HEX)
10384 		display = BASE_DEC;
10385 	if (display == BASE_HEX_DEC)
10386 		display = BASE_HEX;
10387 
10388 	return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
10389 }
10390 
10391 const char *
proto_registrar_get_name(const int n)10392 proto_registrar_get_name(const int n)
10393 {
10394 	header_field_info *hfinfo;
10395 
10396 	PROTO_REGISTRAR_GET_NTH(n, hfinfo);
10397 	return hfinfo->name;
10398 }
10399 
10400 const char *
proto_registrar_get_abbrev(const int n)10401 proto_registrar_get_abbrev(const int n)
10402 {
10403 	header_field_info *hfinfo;
10404 
10405 	PROTO_REGISTRAR_GET_NTH(n, hfinfo);
10406 	return hfinfo->abbrev;
10407 }
10408 
10409 enum ftenum
proto_registrar_get_ftype(const int n)10410 proto_registrar_get_ftype(const int n)
10411 {
10412 	header_field_info *hfinfo;
10413 
10414 	PROTO_REGISTRAR_GET_NTH(n, hfinfo);
10415 	return hfinfo->type;
10416 }
10417 
10418 int
proto_registrar_get_parent(const int n)10419 proto_registrar_get_parent(const int n)
10420 {
10421 	header_field_info *hfinfo;
10422 
10423 	PROTO_REGISTRAR_GET_NTH(n, hfinfo);
10424 	return hfinfo->parent;
10425 }
10426 
10427 gboolean
proto_registrar_is_protocol(const int n)10428 proto_registrar_is_protocol(const int n)
10429 {
10430 	header_field_info *hfinfo;
10431 
10432 	PROTO_REGISTRAR_GET_NTH(n, hfinfo);
10433 	return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? TRUE : FALSE);
10434 }
10435 
10436 /* Returns length of field in packet (not necessarily the length
10437  * in our internal representation, as in the case of IPv4).
10438  * 0 means undeterminable at time of registration
10439  * -1 means the field is not registered. */
10440 gint
proto_registrar_get_length(const int n)10441 proto_registrar_get_length(const int n)
10442 {
10443 	header_field_info *hfinfo;
10444 
10445 	PROTO_REGISTRAR_GET_NTH(n, hfinfo);
10446 	return ftype_length(hfinfo->type);
10447 }
10448 
10449 /* Looks for a protocol or a field in a proto_tree. Returns TRUE if
10450  * it exists anywhere, or FALSE if it exists nowhere. */
10451 gboolean
proto_check_for_protocol_or_field(const proto_tree * tree,const int id)10452 proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
10453 {
10454 	GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
10455 
10456 	if (g_ptr_array_len(ptrs) > 0) {
10457 		return TRUE;
10458 	}
10459 	else {
10460 		return FALSE;
10461 	}
10462 }
10463 
10464 /* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
10465  * This only works if the hfindex was "primed" before the dissection
10466  * took place, as we just pass back the already-created GPtrArray*.
10467  * The caller should *not* free the GPtrArray*; proto_tree_free_node()
10468  * handles that. */
10469 GPtrArray *
proto_get_finfo_ptr_array(const proto_tree * tree,const int id)10470 proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
10471 {
10472 	if (!tree)
10473 		return NULL;
10474 
10475 	if (PTREE_DATA(tree)->interesting_hfids != NULL)
10476 		return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)->interesting_hfids,
10477 					   GINT_TO_POINTER(id));
10478 	else
10479 		return NULL;
10480 }
10481 
10482 gboolean
proto_tracking_interesting_fields(const proto_tree * tree)10483 proto_tracking_interesting_fields(const proto_tree *tree)
10484 {
10485 	GHashTable *interesting_hfids;
10486 
10487 	if (!tree)
10488 		return FALSE;
10489 
10490 	interesting_hfids = PTREE_DATA(tree)->interesting_hfids;
10491 
10492 	return (interesting_hfids != NULL) && g_hash_table_size(interesting_hfids);
10493 }
10494 
10495 /* Helper struct for proto_find_info() and	proto_all_finfos() */
10496 typedef struct {
10497 	GPtrArray *array;
10498 	int	   id;
10499 } ffdata_t;
10500 
10501 /* Helper function for proto_find_info() */
10502 static gboolean
find_finfo(proto_node * node,gpointer data)10503 find_finfo(proto_node *node, gpointer data)
10504 {
10505 	field_info *fi = PNODE_FINFO(node);
10506 	if (fi && fi->hfinfo) {
10507 		if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
10508 			g_ptr_array_add(((ffdata_t*)data)->array, fi);
10509 		}
10510 	}
10511 
10512 	/* Don't stop traversing. */
10513 	return FALSE;
10514 }
10515 
10516 /* Helper function for proto_find_first_info() */
10517 static gboolean
find_first_finfo(proto_node * node,gpointer data)10518 find_first_finfo(proto_node *node, gpointer data)
10519 {
10520 	field_info *fi = PNODE_FINFO(node);
10521 	if (fi && fi->hfinfo) {
10522 		if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
10523 			g_ptr_array_add(((ffdata_t*)data)->array, fi);
10524 
10525 			/* Stop traversing. */
10526 			return TRUE;
10527 		}
10528 	}
10529 
10530 	/* Continue traversing. */
10531 	return FALSE;
10532 }
10533 
10534 /* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
10535 * This works on any proto_tree, primed or unprimed, but actually searches
10536 * the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
10537 * The caller does need to free the returned GPtrArray with
10538 * g_ptr_array_free(<array>, TRUE).
10539 */
10540 GPtrArray *
proto_find_finfo(proto_tree * tree,const int id)10541 proto_find_finfo(proto_tree *tree, const int id)
10542 {
10543 	ffdata_t ffdata;
10544 
10545 	ffdata.array = g_ptr_array_new();
10546 	ffdata.id = id;
10547 
10548 	proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
10549 
10550 	return ffdata.array;
10551 }
10552 
10553 /* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
10554 * This works on any proto_tree, primed or unprimed, but actually searches
10555 * the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
10556 * The caller does need to free the returned GPtrArray with
10557 * g_ptr_array_free(<array>, TRUE).
10558 */
10559 GPtrArray *
proto_find_first_finfo(proto_tree * tree,const int id)10560 proto_find_first_finfo(proto_tree *tree, const int id)
10561 {
10562 	ffdata_t ffdata;
10563 
10564 	ffdata.array = g_ptr_array_new();
10565 	ffdata.id = id;
10566 
10567 	proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
10568 
10569 	return ffdata.array;
10570 }
10571 
10572 /* Helper function for proto_all_finfos() */
10573 static gboolean
every_finfo(proto_node * node,gpointer data)10574 every_finfo(proto_node *node, gpointer data)
10575 {
10576 	field_info *fi = PNODE_FINFO(node);
10577 	if (fi && fi->hfinfo) {
10578 		g_ptr_array_add(((ffdata_t*)data)->array, fi);
10579 	}
10580 
10581 	/* Don't stop traversing. */
10582 	return FALSE;
10583 }
10584 
10585 /* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree. */
10586 GPtrArray *
proto_all_finfos(proto_tree * tree)10587 proto_all_finfos(proto_tree *tree)
10588 {
10589 	ffdata_t ffdata;
10590 
10591 	/* Pre allocate enough space to hold all fields in most cases */
10592 	ffdata.array = g_ptr_array_sized_new(512);
10593 	ffdata.id = 0;
10594 
10595 	proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
10596 
10597 	return ffdata.array;
10598 }
10599 
10600 
10601 typedef struct {
10602 	guint	    offset;
10603 	field_info *finfo;
10604 	tvbuff_t   *tvb;
10605 } offset_search_t;
10606 
10607 static gboolean
check_for_offset(proto_node * node,gpointer data)10608 check_for_offset(proto_node *node, gpointer data)
10609 {
10610 	field_info	*fi        = PNODE_FINFO(node);
10611 	offset_search_t	*offsearch = (offset_search_t *)data;
10612 
10613 	/* !fi == the top most container node which holds nothing */
10614 	if (fi && !proto_item_is_hidden(node) && !proto_item_is_generated(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
10615 		if (offsearch->offset >= (guint) fi->start &&
10616 				offsearch->offset < (guint) (fi->start + fi->length)) {
10617 
10618 			offsearch->finfo = fi;
10619 			return FALSE; /* keep traversing */
10620 		}
10621 	}
10622 	return FALSE; /* keep traversing */
10623 }
10624 
10625 /* Search a proto_tree backwards (from leaves to root) looking for the field
10626  * whose start/length occupies 'offset' */
10627 /* XXX - I couldn't find an easy way to search backwards, so I search
10628  * forwards, w/o stopping. Therefore, the last finfo I find will the be
10629  * the one I want to return to the user. This algorithm is inefficient
10630  * and could be re-done, but I'd have to handle all the children and
10631  * siblings of each node myself. When I have more time I'll do that.
10632  * (yeah right) */
10633 field_info *
proto_find_field_from_offset(proto_tree * tree,guint offset,tvbuff_t * tvb)10634 proto_find_field_from_offset(proto_tree *tree, guint offset, tvbuff_t *tvb)
10635 {
10636 	offset_search_t	offsearch;
10637 
10638 	offsearch.offset = offset;
10639 	offsearch.finfo  = NULL;
10640 	offsearch.tvb    = tvb;
10641 
10642 	proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
10643 
10644 	return offsearch.finfo;
10645 }
10646 
10647 typedef struct {
10648 	gint length;
10649 	gchar *buf;
10650 } decoded_data_t;
10651 
10652 static gboolean
check_for_undecoded(proto_node * node,gpointer data)10653 check_for_undecoded(proto_node *node, gpointer data)
10654 {
10655 	field_info *fi = PNODE_FINFO(node);
10656 	decoded_data_t* decoded = (decoded_data_t*)data;
10657 	gint i;
10658 	guint byte;
10659 	guint bit;
10660 
10661 	if (fi && fi->hfinfo->type != FT_PROTOCOL) {
10662 		for (i = fi->start; i < fi->start + fi->length && i < decoded->length; i++) {
10663 			byte = i / 8;
10664 			bit = i % 8;
10665 			decoded->buf[byte] |= (1 << bit);
10666 		}
10667 	}
10668 
10669 	return FALSE;
10670 }
10671 
10672 gchar*
proto_find_undecoded_data(proto_tree * tree,guint length)10673 proto_find_undecoded_data(proto_tree *tree, guint length)
10674 {
10675 	decoded_data_t decoded;
10676 	decoded.length = length;
10677 	decoded.buf = (gchar*)wmem_alloc0(PNODE_POOL(tree), length / 8 + 1);
10678 
10679 	proto_tree_traverse_pre_order(tree, check_for_undecoded, &decoded);
10680 	return decoded.buf;
10681 }
10682 
10683 /* Dumps the protocols in the registration database to stdout.	An independent
10684  * program can take this output and format it into nice tables or HTML or
10685  * whatever.
10686  *
10687  * There is one record per line. The fields are tab-delimited.
10688  *
10689  * Field 1 = protocol name
10690  * Field 2 = protocol short name
10691  * Field 3 = protocol filter name
10692  */
10693 void
proto_registrar_dump_protocols(void)10694 proto_registrar_dump_protocols(void)
10695 {
10696 	protocol_t *protocol;
10697 	int	    i;
10698 	void	   *cookie = NULL;
10699 
10700 
10701 	i = proto_get_first_protocol(&cookie);
10702 	while (i != -1) {
10703 		protocol = find_protocol_by_id(i);
10704 		printf("%s\t%s\t%s\n", protocol->name, protocol->short_name,
10705 			protocol->filter_name);
10706 		i = proto_get_next_protocol(&cookie);
10707 	}
10708 }
10709 
10710 /* Dumps the value_strings, extended value string headers, range_strings
10711  * or true/false strings for fields that have them.
10712  * There is one record per line. Fields are tab-delimited.
10713  * There are four types of records: Value String, Extended Value String Header,
10714  * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
10715  * the type of record.
10716  *
10717  * Note that a record will be generated only if the value_string,... is referenced
10718  * in a registered hfinfo entry.
10719  *
10720  *
10721  * Value Strings
10722  * -------------
10723  * Field 1 = 'V'
10724  * Field 2 = Field abbreviation to which this value string corresponds
10725  * Field 3 = Integer value
10726  * Field 4 = String
10727  *
10728  * Extended Value String Headers
10729  * -----------------------------
10730  * Field 1 = 'E'
10731  * Field 2 = Field abbreviation to which this extended value string header corresponds
10732  * Field 3 = Extended Value String "Name"
10733  * Field 4 = Number of entries in the associated value_string array
10734  * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
10735  *
10736  * Range Strings
10737  * -------------
10738  * Field 1 = 'R'
10739  * Field 2 = Field abbreviation to which this range string corresponds
10740  * Field 3 = Integer value: lower bound
10741  * Field 4 = Integer value: upper bound
10742  * Field 5 = String
10743  *
10744  * True/False Strings
10745  * ------------------
10746  * Field 1 = 'T'
10747  * Field 2 = Field abbreviation to which this true/false string corresponds
10748  * Field 3 = True String
10749  * Field 4 = False String
10750  */
10751 void
proto_registrar_dump_values(void)10752 proto_registrar_dump_values(void)
10753 {
10754 	header_field_info	*hfinfo;
10755 	int			i, len, vi;
10756 	const value_string	*vals;
10757 	const val64_string	*vals64;
10758 	const range_string	*range;
10759 	const true_false_string	*tfs;
10760 	const unit_name_string	*units;
10761 
10762 	len = gpa_hfinfo.len;
10763 	for (i = 0; i < len ; i++) {
10764 		if (gpa_hfinfo.hfi[i] == NULL)
10765 			continue; /* This is a deregistered protocol or field */
10766 
10767 		PROTO_REGISTRAR_GET_NTH(i, hfinfo);
10768 
10769 		if (hfinfo->id == hf_text_only) {
10770 			continue;
10771 		}
10772 
10773 		/* ignore protocols */
10774 		if (proto_registrar_is_protocol(i)) {
10775 			continue;
10776 		}
10777 		/* process header fields */
10778 #if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
10779 		/*
10780 		 * If this field isn't at the head of the list of
10781 		 * fields with this name, skip this field - all
10782 		 * fields with the same name are really just versions
10783 		 * of the same field stored in different bits, and
10784 		 * should have the same type/radix/value list, and
10785 		 * just differ in their bit masks.	(If a field isn't
10786 		 * a bitfield, but can be, say, 1 or 2 bytes long,
10787 		 * it can just be made FT_UINT16, meaning the
10788 		 * *maximum* length is 2 bytes, and be used
10789 		 * for all lengths.)
10790 		 */
10791 		if (hfinfo->same_name_prev_id != -1)
10792 			continue;
10793 #endif
10794 		vals   = NULL;
10795 		vals64 = NULL;
10796 		range  = NULL;
10797 		tfs    = NULL;
10798 		units  = NULL;
10799 
10800 		if (hfinfo->strings != NULL) {
10801 			if (FIELD_DISPLAY(hfinfo->display) != BASE_CUSTOM &&
10802 			    (hfinfo->type == FT_CHAR  ||
10803 			     hfinfo->type == FT_UINT8  ||
10804 			     hfinfo->type == FT_UINT16 ||
10805 			     hfinfo->type == FT_UINT24 ||
10806 			     hfinfo->type == FT_UINT32 ||
10807 			     hfinfo->type == FT_UINT40 ||
10808 			     hfinfo->type == FT_UINT48 ||
10809 			     hfinfo->type == FT_UINT56 ||
10810 			     hfinfo->type == FT_UINT64 ||
10811 			     hfinfo->type == FT_INT8   ||
10812 			     hfinfo->type == FT_INT16  ||
10813 			     hfinfo->type == FT_INT24  ||
10814 			     hfinfo->type == FT_INT32  ||
10815 			     hfinfo->type == FT_INT40  ||
10816 			     hfinfo->type == FT_INT48  ||
10817 			     hfinfo->type == FT_INT56  ||
10818 			     hfinfo->type == FT_INT64  ||
10819 			     hfinfo->type == FT_FLOAT  ||
10820 			     hfinfo->type == FT_DOUBLE)) {
10821 
10822 				if (hfinfo->display & BASE_RANGE_STRING) {
10823 					range = (const range_string *)hfinfo->strings;
10824 				} else if (hfinfo->display & BASE_EXT_STRING) {
10825 					if (hfinfo->display & BASE_VAL64_STRING) {
10826 						vals64 = VAL64_STRING_EXT_VS_P((const val64_string_ext *)hfinfo->strings);
10827 					} else {
10828 						vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings);
10829 					}
10830 				} else if (hfinfo->display & BASE_VAL64_STRING) {
10831 					vals64 = (const val64_string *)hfinfo->strings;
10832 				} else if (hfinfo->display & BASE_UNIT_STRING) {
10833 					units = (const unit_name_string *)hfinfo->strings;
10834 				} else {
10835 					vals = (const value_string *)hfinfo->strings;
10836 				}
10837 			}
10838 			else if (hfinfo->type == FT_BOOLEAN) {
10839 				tfs = (const struct true_false_string *)hfinfo->strings;
10840 			}
10841 		}
10842 
10843 		/* Print value strings? */
10844 		if (vals) {
10845 			if (hfinfo->display & BASE_EXT_STRING) {
10846 				if (hfinfo->display & BASE_VAL64_STRING) {
10847 					val64_string_ext *vse_p = (val64_string_ext *)hfinfo->strings;
10848 					if (!val64_string_ext_validate(vse_p)) {
10849 						ws_warning("Invalid val64_string_ext ptr for: %s", hfinfo->abbrev);
10850 						continue;
10851 					}
10852 					try_val64_to_str_ext(0, vse_p); /* "prime" the extended val64_string */
10853 					printf("E\t%s\t%u\t%s\t%s\n",
10854 					       hfinfo->abbrev,
10855 					       VAL64_STRING_EXT_VS_NUM_ENTRIES(vse_p),
10856 					       VAL64_STRING_EXT_VS_NAME(vse_p),
10857 					       val64_string_ext_match_type_str(vse_p));
10858 				} else {
10859 					value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
10860 					if (!value_string_ext_validate(vse_p)) {
10861 						ws_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev);
10862 						continue;
10863 					}
10864 					try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
10865 					printf("E\t%s\t%u\t%s\t%s\n",
10866 					       hfinfo->abbrev,
10867 					       VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p),
10868 					       VALUE_STRING_EXT_VS_NAME(vse_p),
10869 					       value_string_ext_match_type_str(vse_p));
10870 				}
10871 			}
10872 			vi = 0;
10873 			while (vals[vi].strptr) {
10874 				/* Print in the proper base */
10875 				if (hfinfo->type == FT_CHAR) {
10876 					if (g_ascii_isprint(vals[vi].value)) {
10877 						printf("V\t%s\t'%c'\t%s\n",
10878 						       hfinfo->abbrev,
10879 						       vals[vi].value,
10880 						       vals[vi].strptr);
10881 					} else {
10882 						if (hfinfo->display == BASE_HEX) {
10883 							printf("V\t%s\t'\\x%02x'\t%s\n",
10884 							       hfinfo->abbrev,
10885 							       vals[vi].value,
10886 							       vals[vi].strptr);
10887 						}
10888 						else {
10889 							printf("V\t%s\t'\\%03o'\t%s\n",
10890 							       hfinfo->abbrev,
10891 							       vals[vi].value,
10892 							       vals[vi].strptr);
10893 						}
10894 					}
10895 				} else {
10896 					if (hfinfo->display == BASE_HEX) {
10897 						printf("V\t%s\t0x%x\t%s\n",
10898 						       hfinfo->abbrev,
10899 						       vals[vi].value,
10900 						       vals[vi].strptr);
10901 					}
10902 					else {
10903 						printf("V\t%s\t%u\t%s\n",
10904 						       hfinfo->abbrev,
10905 						       vals[vi].value,
10906 						       vals[vi].strptr);
10907 					}
10908 				}
10909 				vi++;
10910 			}
10911 		}
10912 		else if (vals64) {
10913 			vi = 0;
10914 			while (vals64[vi].strptr) {
10915 				printf("V64\t%s\t%" G_GINT64_MODIFIER "u\t%s\n",
10916 				       hfinfo->abbrev,
10917 				       vals64[vi].value,
10918 				       vals64[vi].strptr);
10919 				vi++;
10920 			}
10921 		}
10922 
10923 		/* print range strings? */
10924 		else if (range) {
10925 			vi = 0;
10926 			while (range[vi].strptr) {
10927 				/* Print in the proper base */
10928 				if (FIELD_DISPLAY(hfinfo->display) == BASE_HEX) {
10929 					printf("R\t%s\t0x%x\t0x%x\t%s\n",
10930 					       hfinfo->abbrev,
10931 					       range[vi].value_min,
10932 					       range[vi].value_max,
10933 					       range[vi].strptr);
10934 				}
10935 				else {
10936 					printf("R\t%s\t%u\t%u\t%s\n",
10937 					       hfinfo->abbrev,
10938 					       range[vi].value_min,
10939 					       range[vi].value_max,
10940 					       range[vi].strptr);
10941 				}
10942 				vi++;
10943 			}
10944 		}
10945 
10946 		/* Print true/false strings? */
10947 		else if (tfs) {
10948 			printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
10949 			       tfs->true_string, tfs->false_string);
10950 		}
10951 		/* Print unit strings? */
10952 		else if (units) {
10953 			printf("U\t%s\t%s\t%s\n", hfinfo->abbrev,
10954 			       units->singular, units->plural ? units->plural : "(no plural)");
10955 		}
10956 	}
10957 }
10958 
10959 /* Prints the number of registered fields.
10960  * Useful for determining an appropriate value for
10961  * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
10962  *
10963  * Returns FALSE if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
10964  * the number of fields, TRUE otherwise.
10965  */
10966 gboolean
proto_registrar_dump_fieldcount(void)10967 proto_registrar_dump_fieldcount(void)
10968 {
10969 	guint32			i;
10970 	header_field_info	*hfinfo;
10971 	guint32			deregistered_count = 0;
10972 	guint32			same_name_count = 0;
10973 	guint32			protocol_count = 0;
10974 
10975 	for (i = 0; i < gpa_hfinfo.len; i++) {
10976 		if (gpa_hfinfo.hfi[i] == NULL) {
10977 			deregistered_count++;
10978 			continue; /* This is a deregistered protocol or header field */
10979 		}
10980 
10981 		PROTO_REGISTRAR_GET_NTH(i, hfinfo);
10982 
10983 		if (proto_registrar_is_protocol(i))
10984 			protocol_count++;
10985 
10986 		if (hfinfo->same_name_prev_id != -1)
10987 			same_name_count++;
10988 	}
10989 
10990 	printf("There are %u header fields registered, of which:\n"
10991 		"\t%u are deregistered\n"
10992 		"\t%u are protocols\n"
10993 		"\t%u have the same name as another field\n\n",
10994 		gpa_hfinfo.len, deregistered_count, protocol_count,
10995 		same_name_count);
10996 
10997 	printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM,
10998 		(gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM) ?
10999 		    "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
11000 		    "\n");
11001 
11002 	printf("The header field table consumes %u KiB of memory.\n",
11003 		(unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
11004 	printf("The fields themselves consume %u KiB of memory.\n",
11005 		(unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
11006 
11007 	return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM);
11008 }
11009 
11010 static void
elastic_add_base_mapping(json_dumper * dumper)11011 elastic_add_base_mapping(json_dumper *dumper)
11012 {
11013 	json_dumper_set_member_name(dumper, "index_patterns");
11014 	json_dumper_value_string(dumper, "packets-*");
11015 
11016 	json_dumper_set_member_name(dumper, "settings");
11017 	json_dumper_begin_object(dumper);
11018 	json_dumper_set_member_name(dumper, "index.mapping.total_fields.limit");
11019 	json_dumper_value_anyf(dumper, "%d", 1000000);
11020 	json_dumper_end_object(dumper);
11021 }
11022 
11023 static gchar*
ws_type_to_elastic(guint type _U_)11024 ws_type_to_elastic(guint type _U_)
11025 {
11026 	switch(type) {
11027 		case FT_UINT16:
11028 		case FT_INT16:
11029 		case FT_INT32:
11030 		case FT_UINT24:
11031 		case FT_INT24:
11032 			return "integer";
11033 		case FT_INT8:
11034 		case FT_UINT8:
11035 			return "short";
11036 		case FT_FRAMENUM:
11037 		case FT_UINT32:
11038 		case FT_UINT40:
11039 		case FT_UINT48:
11040 		case FT_UINT56:
11041 		case FT_UINT64: // Actually it's not handled by 'long' elastic type.
11042 		case FT_INT48:
11043 		case FT_INT64:
11044 			return "long";
11045 		case FT_FLOAT:
11046 		case FT_DOUBLE:
11047 			return "float";
11048 		case FT_IPv6:
11049 		case FT_IPv4:
11050 			return "ip";
11051 		case FT_ABSOLUTE_TIME:
11052 		case FT_RELATIVE_TIME:
11053 			return "date";
11054 		case FT_BYTES:
11055 		case FT_UINT_BYTES:
11056 			return "byte";
11057 		case FT_BOOLEAN:
11058 			return "boolean";
11059 		default:
11060 			return NULL;
11061 	}
11062 }
11063 
11064 static gchar*
dot_to_underscore(gchar * str)11065 dot_to_underscore(gchar* str)
11066 {
11067 	unsigned i;
11068 	for (i = 0; i < strlen(str); i++) {
11069 		if (str[i] == '.')
11070 			str[i] = '_';
11071 	}
11072 	return str;
11073 }
11074 
11075 /* Dumps a mapping file for ElasticSearch
11076  */
11077 void
proto_registrar_dump_elastic(const gchar * filter)11078 proto_registrar_dump_elastic(const gchar* filter)
11079 {
11080 	header_field_info *hfinfo;
11081 	header_field_info *parent_hfinfo;
11082 	guint i;
11083 	gboolean open_object = TRUE;
11084 	const char* prev_proto = NULL;
11085 	gchar* str;
11086 	gchar** protos = NULL;
11087 	gchar* proto;
11088 	gboolean found;
11089 	guint j;
11090 	gchar* type;
11091 
11092 	/* We have filtering protocols. Extract them. */
11093 	if (filter) {
11094 		protos = g_strsplit(filter, ",", -1);
11095 	}
11096 
11097 	/*
11098 	 * To help tracking down the json tree, objects have been appended with a comment:
11099 	 * n.label -> where n is the indentation level and label the name of the object
11100 	 */
11101 
11102 	json_dumper dumper = {
11103 		.output_file = stdout,
11104 		.flags = JSON_DUMPER_FLAGS_PRETTY_PRINT,
11105 	};
11106 	json_dumper_begin_object(&dumper); // 1.root
11107 	elastic_add_base_mapping(&dumper);
11108 
11109 	json_dumper_set_member_name(&dumper, "mappings");
11110 	json_dumper_begin_object(&dumper); // 2.mappings
11111 	json_dumper_set_member_name(&dumper, "doc");
11112 
11113 	json_dumper_begin_object(&dumper); // 3.doc
11114 	json_dumper_set_member_name(&dumper, "dynamic");
11115 	json_dumper_value_anyf(&dumper, "false");
11116 
11117 	json_dumper_set_member_name(&dumper, "properties");
11118 	json_dumper_begin_object(&dumper); // 4.properties
11119 	json_dumper_set_member_name(&dumper, "timestamp");
11120 	json_dumper_begin_object(&dumper); // 5.timestamp
11121 	json_dumper_set_member_name(&dumper, "type");
11122 	json_dumper_value_string(&dumper, "date");
11123 	json_dumper_end_object(&dumper); // 5.timestamp
11124 
11125 	json_dumper_set_member_name(&dumper, "layers");
11126 	json_dumper_begin_object(&dumper); // 5.layers
11127 	json_dumper_set_member_name(&dumper, "properties");
11128 	json_dumper_begin_object(&dumper); // 6.properties
11129 
11130 	for (i = 0; i < gpa_hfinfo.len; i++) {
11131 		if (gpa_hfinfo.hfi[i] == NULL)
11132 			continue; /* This is a deregistered protocol or header field */
11133 
11134 		PROTO_REGISTRAR_GET_NTH(i, hfinfo);
11135 
11136 		/*
11137 		 * Skip the pseudo-field for "proto_tree_add_text()" since
11138 		 * we don't want it in the list of filterable protocols.
11139 		 */
11140 		if (hfinfo->id == hf_text_only)
11141 			continue;
11142 
11143 		if (!proto_registrar_is_protocol(i)) {
11144 			PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
11145 
11146 			/*
11147 			 * Skip the field if filter protocols have been set and this one's
11148 			 * parent is not listed.
11149 			 */
11150 			if (protos) {
11151 				found = FALSE;
11152 				j = 0;
11153 				proto = protos[0];
11154 				while(proto) {
11155 					if (!g_strcmp0(proto, parent_hfinfo->abbrev)) {
11156 						found = TRUE;
11157 						break;
11158 					}
11159 					j++;
11160 					proto = protos[j];
11161 				}
11162 				if (!found)
11163 					continue;
11164 			}
11165 
11166 			if (prev_proto && g_strcmp0(parent_hfinfo->abbrev, prev_proto)) {
11167 				json_dumper_end_object(&dumper); // 8.properties
11168 				json_dumper_end_object(&dumper); // 7.parent_hfinfo->abbrev
11169 				open_object = TRUE;
11170 			}
11171 
11172 			prev_proto = parent_hfinfo->abbrev;
11173 
11174 			if (open_object) {
11175 				json_dumper_set_member_name(&dumper, parent_hfinfo->abbrev);
11176 				json_dumper_begin_object(&dumper); // 7.parent_hfinfo->abbrev
11177 				json_dumper_set_member_name(&dumper, "properties");
11178 				json_dumper_begin_object(&dumper); // 8.properties
11179 				open_object = FALSE;
11180 			}
11181 			/* Skip the fields that would map into string. This is the default in elasticsearch. */
11182 			type = ws_type_to_elastic(hfinfo->type);
11183 			if (type) {
11184 				str = g_strdup_printf("%s_%s", prev_proto, hfinfo->abbrev);
11185 				json_dumper_set_member_name(&dumper, dot_to_underscore(str));
11186 				g_free(str);
11187 				json_dumper_begin_object(&dumper); // 9.hfinfo->abbrev
11188 				json_dumper_set_member_name(&dumper, "type");
11189 				json_dumper_value_string(&dumper, type);
11190 				json_dumper_end_object(&dumper); // 9.hfinfo->abbrev
11191 			}
11192 		}
11193 	}
11194 
11195 	if (prev_proto) {
11196 		json_dumper_end_object(&dumper); // 8.properties
11197 		json_dumper_end_object(&dumper); // 7.parent_hfinfo->abbrev
11198 	}
11199 
11200 	json_dumper_end_object(&dumper); // 6.properties
11201 	json_dumper_end_object(&dumper); // 5.layers
11202 	json_dumper_end_object(&dumper); // 4.properties
11203 	json_dumper_end_object(&dumper); // 3.doc
11204 	json_dumper_end_object(&dumper); // 2.mappings
11205 	json_dumper_end_object(&dumper); // 1.root
11206 	gboolean ret = json_dumper_finish(&dumper);
11207 	DISSECTOR_ASSERT(ret);
11208 
11209 	g_strfreev(protos);
11210 }
11211 
11212 /* Dumps the contents of the registration database to stdout. An independent
11213  * program can take this output and format it into nice tables or HTML or
11214  * whatever.
11215  *
11216  * There is one record per line. Each record is either a protocol or a header
11217  * field, differentiated by the first field. The fields are tab-delimited.
11218  *
11219  * Protocols
11220  * ---------
11221  * Field 1 = 'P'
11222  * Field 2 = descriptive protocol name
11223  * Field 3 = protocol abbreviation
11224  *
11225  * Header Fields
11226  * -------------
11227  * Field 1 = 'F'
11228  * Field 2 = descriptive field name
11229  * Field 3 = field abbreviation
11230  * Field 4 = type ( textual representation of the the ftenum type )
11231  * Field 5 = parent protocol abbreviation
11232  * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
11233  * Field 7 = bitmask: format: hex: 0x....
11234  * Field 8 = blurb describing field
11235  */
11236 void
proto_registrar_dump_fields(void)11237 proto_registrar_dump_fields(void)
11238 {
11239 	header_field_info *hfinfo, *parent_hfinfo;
11240 	int		   i, len;
11241 	const char	  *enum_name;
11242 	const char	  *base_name;
11243 	const char	  *blurb;
11244 	char		   width[5];
11245 
11246 	len = gpa_hfinfo.len;
11247 	for (i = 0; i < len ; i++) {
11248 		if (gpa_hfinfo.hfi[i] == NULL)
11249 			continue; /* This is a deregistered protocol or header field */
11250 
11251 		PROTO_REGISTRAR_GET_NTH(i, hfinfo);
11252 
11253 		/*
11254 		 * Skip the pseudo-field for "proto_tree_add_text()" since
11255 		 * we don't want it in the list of filterable fields.
11256 		 */
11257 		if (hfinfo->id == hf_text_only)
11258 			continue;
11259 
11260 		/* format for protocols */
11261 		if (proto_registrar_is_protocol(i)) {
11262 			printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
11263 		}
11264 		/* format for header fields */
11265 		else {
11266 			/*
11267 			 * If this field isn't at the head of the list of
11268 			 * fields with this name, skip this field - all
11269 			 * fields with the same name are really just versions
11270 			 * of the same field stored in different bits, and
11271 			 * should have the same type/radix/value list, and
11272 			 * just differ in their bit masks.	(If a field isn't
11273 			 * a bitfield, but can be, say, 1 or 2 bytes long,
11274 			 * it can just be made FT_UINT16, meaning the
11275 			 * *maximum* length is 2 bytes, and be used
11276 			 * for all lengths.)
11277 			 */
11278 			if (hfinfo->same_name_prev_id != -1)
11279 				continue;
11280 
11281 			PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
11282 
11283 			enum_name = ftype_name(hfinfo->type);
11284 			base_name = "";
11285 
11286 			if (hfinfo->type == FT_CHAR  ||
11287 			    hfinfo->type == FT_UINT8  ||
11288 			    hfinfo->type == FT_UINT16 ||
11289 			    hfinfo->type == FT_UINT24 ||
11290 			    hfinfo->type == FT_UINT32 ||
11291 			    hfinfo->type == FT_UINT40 ||
11292 			    hfinfo->type == FT_UINT48 ||
11293 			    hfinfo->type == FT_UINT56 ||
11294 			    hfinfo->type == FT_UINT64 ||
11295 			    hfinfo->type == FT_INT8   ||
11296 			    hfinfo->type == FT_INT16  ||
11297 			    hfinfo->type == FT_INT24  ||
11298 			    hfinfo->type == FT_INT32  ||
11299 			    hfinfo->type == FT_INT40 ||
11300 			    hfinfo->type == FT_INT48 ||
11301 			    hfinfo->type == FT_INT56 ||
11302 			    hfinfo->type == FT_INT64) {
11303 
11304 				switch (FIELD_DISPLAY(hfinfo->display)) {
11305 					case BASE_NONE:
11306 					case BASE_DEC:
11307 					case BASE_HEX:
11308 					case BASE_OCT:
11309 					case BASE_DEC_HEX:
11310 					case BASE_HEX_DEC:
11311 					case BASE_CUSTOM:
11312 					case BASE_PT_UDP:
11313 					case BASE_PT_TCP:
11314 					case BASE_PT_DCCP:
11315 					case BASE_PT_SCTP:
11316 					case BASE_OUI:
11317 						base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display), hf_display, "????");
11318 						break;
11319 					default:
11320 						base_name = "????";
11321 						break;
11322 				}
11323 			} else if (hfinfo->type == FT_BOOLEAN) {
11324 				/* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
11325 				g_snprintf(width, sizeof(width), "%d", hfinfo->display);
11326 				base_name = width;
11327 			}
11328 
11329 			blurb = hfinfo->blurb;
11330 			if (blurb == NULL)
11331 				blurb = "";
11332 			else if (strlen(blurb) == 0)
11333 				blurb = "\"\"";
11334 
11335 			printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" G_GINT64_MODIFIER "x\t%s\n",
11336 				hfinfo->name, hfinfo->abbrev, enum_name,
11337 				parent_hfinfo->abbrev, base_name,
11338 				hfinfo->bitmask, blurb);
11339 		}
11340 	}
11341 }
11342 
11343 /* Dumps field types and descriptive names to stdout. An independent
11344  * program can take this output and format it into nice tables or HTML or
11345  * whatever.
11346  *
11347  * There is one record per line. The fields are tab-delimited.
11348  *
11349  * Field 1 = field type name, e.g. FT_UINT8
11350  * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
11351  */
11352 void
proto_registrar_dump_ftypes(void)11353 proto_registrar_dump_ftypes(void)
11354 {
11355 	int fte;
11356 
11357 	for (fte = 0; fte < FT_NUM_TYPES; fte++) {
11358 		printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
11359 	}
11360 }
11361 
11362 /* This function indicates whether it's possible to construct a
11363  * "match selected" display filter string for the specified field,
11364  * returns an indication of whether it's possible, and, if it's
11365  * possible and "filter" is non-null, constructs the filter and
11366  * sets "*filter" to point to it.
11367  * You do not need to [g_]free() this string since it will be automatically
11368  * freed once the next packet is dissected.
11369  */
11370 static gboolean
construct_match_selected_string(field_info * finfo,epan_dissect_t * edt,char ** filter)11371 construct_match_selected_string(field_info *finfo, epan_dissect_t *edt,
11372 				char **filter)
11373 {
11374 	header_field_info *hfinfo;
11375 	int		   abbrev_len;
11376 	char		  *ptr;
11377 	int		   buf_len;
11378 	int		   dfilter_len, i;
11379 	gint		   start, length, length_remaining;
11380 	guint8		   c;
11381 	gchar		   is_signed_num = FALSE;
11382 
11383 	if (!finfo)
11384 		return FALSE;
11385 
11386 	hfinfo     = finfo->hfinfo;
11387 	DISSECTOR_ASSERT(hfinfo);
11388 	abbrev_len = (int) strlen(hfinfo->abbrev);
11389 
11390 	if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display) == BASE_NONE) {
11391 		const gchar *str = NULL;
11392 
11393 		switch (hfinfo->type) {
11394 
11395 		case FT_INT8:
11396 		case FT_INT16:
11397 		case FT_INT24:
11398 		case FT_INT32:
11399 			str = hf_try_val_to_str(fvalue_get_sinteger(&finfo->value), hfinfo);
11400 			break;
11401 
11402 		case FT_CHAR:
11403 		case FT_UINT8:
11404 		case FT_UINT16:
11405 		case FT_UINT24:
11406 		case FT_UINT32:
11407 			str = hf_try_val_to_str(fvalue_get_uinteger(&finfo->value), hfinfo);
11408 			break;
11409 
11410 		default:
11411 			break;
11412 		}
11413 
11414 		if (str != NULL && filter != NULL) {
11415 			*filter = wmem_strdup_printf(NULL, "%s == \"%s\"", hfinfo->abbrev, str);
11416 			return TRUE;
11417 		}
11418 	}
11419 
11420 	/*
11421 	 * XXX - we can't use the "val_to_string_repr" and "string_repr_len"
11422 	 * functions for FT_UINT and FT_INT types, as we choose the base in
11423 	 * the string expression based on the display base of the field.
11424 	 *
11425 	 * Note that the base does matter, as this is also used for
11426 	 * the protocolinfo tap.
11427 	 *
11428 	 * It might be nice to use them in "proto_item_fill_label()"
11429 	 * as well, although, there, you'd have to deal with the base
11430 	 * *and* with resolved values for addresses.
11431 	 *
11432 	 * Perhaps we need two different val_to_string routines, one
11433 	 * to generate items for display filters and one to generate
11434 	 * strings for display, and pass to both of them the
11435 	 * "display" and "strings" values in the header_field_info
11436 	 * structure for the field, so they can get the base and,
11437 	 * if the field is Boolean or an enumerated integer type,
11438 	 * the tables used to generate human-readable values.
11439 	 */
11440 	switch (hfinfo->type) {
11441 
11442 		case FT_CHAR:
11443 			if (filter != NULL) {
11444 				guint32 number;
11445 
11446 				char buf [48];
11447 				const char *out;
11448 
11449 				number = fvalue_get_uinteger(&finfo->value);
11450 
11451 				out = hfinfo_char_value_format(hfinfo, buf, number);
11452 
11453 				*filter = wmem_strdup_printf(NULL, "%s == %s", hfinfo->abbrev, out);
11454 			}
11455 			break;
11456 
11457 		case FT_INT8:
11458 		case FT_INT16:
11459 		case FT_INT24:
11460 		case FT_INT32:
11461 			is_signed_num = TRUE;
11462 			/* FALLTHRU */
11463 		case FT_UINT8:
11464 		case FT_UINT16:
11465 		case FT_UINT24:
11466 		case FT_UINT32:
11467 		case FT_FRAMENUM:
11468 			if (filter != NULL) {
11469 				guint32 number;
11470 
11471 				char buf[32];
11472 				const char *out;
11473 
11474 				if (is_signed_num)
11475 					number = fvalue_get_sinteger(&finfo->value);
11476 				else
11477 					number = fvalue_get_uinteger(&finfo->value);
11478 
11479 				out = hfinfo_numeric_value_format(hfinfo, buf, number);
11480 
11481 				*filter = wmem_strdup_printf(NULL, "%s == %s", hfinfo->abbrev, out);
11482 			}
11483 			break;
11484 
11485 		case FT_INT40:
11486 		case FT_INT48:
11487 		case FT_INT56:
11488 		case FT_INT64:
11489 			is_signed_num = TRUE;
11490 			/* FALLTHRU */
11491 		case FT_UINT40:
11492 		case FT_UINT48:
11493 		case FT_UINT56:
11494 		case FT_UINT64:
11495 			if (filter != NULL) {
11496 				guint64 number;
11497 
11498 				char buf [48];
11499 				const char *out;
11500 
11501 				if (is_signed_num)
11502 					number = fvalue_get_sinteger64(&finfo->value);
11503 				else
11504 					number = fvalue_get_uinteger64(&finfo->value);
11505 
11506 				out = hfinfo_numeric_value_format64(hfinfo, buf, number);
11507 
11508 				*filter = wmem_strdup_printf(NULL, "%s == %s", hfinfo->abbrev, out);
11509 			}
11510 			break;
11511 
11512 		case FT_PROTOCOL:
11513 			if (filter != NULL)
11514 				*filter = wmem_strdup(NULL, finfo->hfinfo->abbrev);
11515 			break;
11516 
11517 		case FT_NONE:
11518 			/*
11519 			 * If the length is 0, just match the name of the
11520 			 * field.
11521 			 *
11522 			 * (Also check for negative values, just in case,
11523 			 * as we'll cast it to an unsigned value later.)
11524 			 */
11525 			length = finfo->length;
11526 			if (length == 0) {
11527 				if (filter != NULL)
11528 					*filter = wmem_strdup(NULL, finfo->hfinfo->abbrev);
11529 				break;
11530 			}
11531 			if (length < 0)
11532 				return FALSE;
11533 
11534 			/*
11535 			 * This doesn't have a value, so we'd match
11536 			 * on the raw bytes at this address.
11537 			 *
11538 			 * Should we be allowed to access to the raw bytes?
11539 			 * If "edt" is NULL, the answer is "no".
11540 			 */
11541 			if (edt == NULL)
11542 				return FALSE;
11543 
11544 			/*
11545 			 * Is this field part of the raw frame tvbuff?
11546 			 * If not, we can't use "frame[N:M]" to match
11547 			 * it.
11548 			 *
11549 			 * XXX - should this be frame-relative, or
11550 			 * protocol-relative?
11551 			 *
11552 			 * XXX - does this fallback for non-registered
11553 			 * fields even make sense?
11554 			 */
11555 			if (finfo->ds_tvb != edt->tvb)
11556 				return FALSE;	/* you lose */
11557 
11558 			/*
11559 			 * Don't go past the end of that tvbuff.
11560 			 */
11561 			length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
11562 			if (length > length_remaining)
11563 				length = length_remaining;
11564 			if (length <= 0)
11565 				return FALSE;
11566 
11567 			if (filter != NULL) {
11568 				start = finfo->start;
11569 				buf_len = 32 + length * 3;
11570 				*filter = (char *)wmem_alloc0(NULL, buf_len);
11571 				ptr = *filter;
11572 
11573 				ptr += g_snprintf(ptr, (gulong) (buf_len-(ptr-*filter)),
11574 					"frame[%d:%d] == ", finfo->start, length);
11575 				for (i=0; i<length; i++) {
11576 					c = tvb_get_guint8(finfo->ds_tvb, start);
11577 					start++;
11578 					if (i == 0 ) {
11579 						ptr += g_snprintf(ptr, (gulong) (buf_len-(ptr-*filter)), "%02x", c);
11580 					}
11581 					else {
11582 						ptr += g_snprintf(ptr, (gulong) (buf_len-(ptr-*filter)), ":%02x", c);
11583 					}
11584 				}
11585 			}
11586 			break;
11587 
11588 		/* By default, use the fvalue's "to_string_repr" method. */
11589 		default:
11590 			/* Figure out the string length needed.
11591 			 *	The ft_repr length.
11592 			 *	4 bytes for " == ".
11593 			 *	1 byte for trailing NUL.
11594 			 */
11595 			if (filter != NULL) {
11596 				char* str;
11597 				dfilter_len = fvalue_string_repr_len(&finfo->value,
11598 						FTREPR_DFILTER, finfo->hfinfo->display);
11599 				dfilter_len += abbrev_len + 4 + 1;
11600 				*filter = (char *)wmem_alloc0(NULL, dfilter_len);
11601 
11602 				/* Create the string */
11603 				str = fvalue_to_string_repr(NULL, &finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
11604 				g_snprintf(*filter, dfilter_len, "%s == %s", hfinfo->abbrev, str);
11605 				wmem_free(NULL, str);
11606 			}
11607 			break;
11608 	}
11609 
11610 	return TRUE;
11611 }
11612 
11613 /*
11614  * Returns TRUE if we can do a "match selected" on the field, FALSE
11615  * otherwise.
11616  */
11617 gboolean
proto_can_match_selected(field_info * finfo,epan_dissect_t * edt)11618 proto_can_match_selected(field_info *finfo, epan_dissect_t *edt)
11619 {
11620 	return construct_match_selected_string(finfo, edt, NULL);
11621 }
11622 
11623 /* This function attempts to construct a "match selected" display filter
11624  * string for the specified field; if it can do so, it returns a pointer
11625  * to the string, otherwise it returns NULL.
11626  *
11627  * The string is wmem allocated and must be freed with "wmem_free(NULL, ...)".
11628  */
11629 char *
proto_construct_match_selected_string(field_info * finfo,epan_dissect_t * edt)11630 proto_construct_match_selected_string(field_info *finfo, epan_dissect_t *edt)
11631 {
11632 	char *filter = NULL;
11633 
11634 	if (!construct_match_selected_string(finfo, edt, &filter))
11635 	{
11636 		wmem_free(NULL, filter);
11637 		return NULL;
11638 	}
11639 	return filter;
11640 }
11641 
11642 /* This function is common code for all proto_tree_add_bitmask... functions.
11643  */
11644 
11645 static gboolean
proto_item_add_bitmask_tree(proto_item * item,tvbuff_t * tvb,const int offset,const int len,const gint ett,int * const * fields,const int flags,gboolean first,gboolean use_parent_tree,proto_tree * tree,guint64 value)11646 proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
11647 			    const int len, const gint ett, int * const *fields,
11648 			    const int flags, gboolean first,
11649 			    gboolean use_parent_tree,
11650 			    proto_tree* tree, guint64 value)
11651 {
11652 	guint64            available_bits = G_MAXUINT64;
11653 	guint64            bitmask = 0;
11654 	guint64            tmpval;
11655 	header_field_info *hf;
11656 	guint32            integer32;
11657 	gint               bit_offset;
11658 	gint               no_of_bits;
11659 
11660 	if (!*fields)
11661 		REPORT_DISSECTOR_BUG("Illegal call of proto_item_add_bitmask_tree without fields");
11662 
11663 	if (len < 0 || len > 8)
11664 		REPORT_DISSECTOR_BUG("Invalid len: %d", len);
11665 	/**
11666 	 * packet-frame.c uses len=0 since the value is taken from the packet
11667 	 * metadata, not the packet bytes. In that case, assume that all bits
11668 	 * in the provided value are valid.
11669 	 */
11670 	if (len > 0) {
11671 		available_bits >>= (8 - (guint)len)*8;
11672 	}
11673 
11674 	if (use_parent_tree == FALSE)
11675 		tree = proto_item_add_subtree(item, ett);
11676 
11677 	while (*fields) {
11678 		guint64 present_bits;
11679 		PROTO_REGISTRAR_GET_NTH(**fields,hf);
11680 		DISSECTOR_ASSERT_HINT(hf->bitmask != 0, hf->abbrev);
11681 
11682 		bitmask |= hf->bitmask;
11683 
11684 		/* Skip fields that aren't fully present */
11685 		present_bits = available_bits & hf->bitmask;
11686 		if (present_bits != hf->bitmask) {
11687 			fields++;
11688 			continue;
11689 		}
11690 
11691 		switch (hf->type) {
11692 		case FT_CHAR:
11693 		case FT_UINT8:
11694 		case FT_UINT16:
11695 		case FT_UINT24:
11696 		case FT_UINT32:
11697 			proto_tree_add_uint(tree, **fields, tvb, offset, len, (guint32)value);
11698 			break;
11699 
11700 		case FT_INT8:
11701 		case FT_INT16:
11702 		case FT_INT24:
11703 		case FT_INT32:
11704 			proto_tree_add_int(tree, **fields, tvb, offset, len, (gint32)value);
11705 			break;
11706 
11707 		case FT_UINT40:
11708 		case FT_UINT48:
11709 		case FT_UINT56:
11710 		case FT_UINT64:
11711 			proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
11712 			break;
11713 
11714 		case FT_INT40:
11715 		case FT_INT48:
11716 		case FT_INT56:
11717 		case FT_INT64:
11718 			proto_tree_add_int64(tree, **fields, tvb, offset, len, (gint64)value);
11719 			break;
11720 
11721 		case FT_BOOLEAN:
11722 			proto_tree_add_boolean64(tree, **fields, tvb, offset, len, value);
11723 			break;
11724 
11725 		default:
11726 			REPORT_DISSECTOR_BUG("field %s has type %d (%s) not handled in proto_item_add_bitmask_tree()",
11727 					     hf->abbrev,
11728 					     hf->type,
11729 					     ftype_name(hf->type));
11730 			break;
11731 		}
11732 		if (flags & BMT_NO_APPEND) {
11733 			fields++;
11734 			continue;
11735 		}
11736 		tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
11737 
11738 		switch (hf->type) {
11739 		case FT_CHAR:
11740 			if (hf->display == BASE_CUSTOM) {
11741 				gchar lbl[ITEM_LABEL_LENGTH];
11742 				const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
11743 
11744 				DISSECTOR_ASSERT(fmtfunc);
11745 				fmtfunc(lbl, (guint32) tmpval);
11746 				proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
11747 						hf->name, lbl);
11748 				first = FALSE;
11749 			}
11750 			else if (hf->strings) {
11751 				proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
11752 						       hf->name, hf_try_val_to_str_const((guint32) tmpval, hf, "Unknown"));
11753 				first = FALSE;
11754 			}
11755 			else if (!(flags & BMT_NO_INT)) {
11756 				char buf[32];
11757 				const char *out;
11758 
11759 				if (!first) {
11760 					proto_item_append_text(item, ", ");
11761 				}
11762 
11763 				out = hfinfo_char_value_format(hf, buf, (guint32) tmpval);
11764 				proto_item_append_text(item, "%s: %s", hf->name, out);
11765 				first = FALSE;
11766 			}
11767 
11768 			break;
11769 
11770 		case FT_UINT8:
11771 		case FT_UINT16:
11772 		case FT_UINT24:
11773 		case FT_UINT32:
11774 			if (hf->display == BASE_CUSTOM) {
11775 				gchar lbl[ITEM_LABEL_LENGTH];
11776 				const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
11777 
11778 				DISSECTOR_ASSERT(fmtfunc);
11779 				fmtfunc(lbl, (guint32) tmpval);
11780 				proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
11781 						hf->name, lbl);
11782 				first = FALSE;
11783 			}
11784 			else if ((hf->strings) &&(!(hf->display & BASE_UNIT_STRING))) {
11785 				proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
11786 										hf->name, hf_try_val_to_str_const((guint32) tmpval, hf, "Unknown"));
11787 				first = FALSE;
11788 			}
11789 			else if (!(flags & BMT_NO_INT)) {
11790 				char buf[32];
11791 				const char *out;
11792 
11793 				if (!first) {
11794 					proto_item_append_text(item, ", ");
11795 				}
11796 
11797 				out = hfinfo_number_value_format(hf, buf, (guint32) tmpval);
11798 				if (hf->display & BASE_UNIT_STRING) {
11799 					proto_item_append_text(item, "%s: %s%s", hf->name, out, unit_name_string_get_value((guint32) tmpval, (const unit_name_string*)hf->strings));
11800 				} else {
11801 					proto_item_append_text(item, "%s: %s", hf->name, out);
11802 				}
11803 				first = FALSE;
11804 			}
11805 
11806 			break;
11807 
11808 		case FT_INT8:
11809 		case FT_INT16:
11810 		case FT_INT24:
11811 		case FT_INT32:
11812 			integer32 = (guint32) tmpval;
11813 			if (hf->bitmask) {
11814 				no_of_bits = ws_count_ones(hf->bitmask);
11815 				integer32 = ws_sign_ext32(integer32, no_of_bits);
11816 			}
11817 			if (hf->display == BASE_CUSTOM) {
11818 				gchar lbl[ITEM_LABEL_LENGTH];
11819 				const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
11820 
11821 				DISSECTOR_ASSERT(fmtfunc);
11822 				fmtfunc(lbl, (gint32) integer32);
11823 				proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
11824 						hf->name, lbl);
11825 				first = FALSE;
11826 			}
11827 			else if ((hf->strings) &&(!(hf->display & BASE_UNIT_STRING))) {
11828 				proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
11829 						hf->name, hf_try_val_to_str_const((gint32) integer32, hf, "Unknown"));
11830 				first = FALSE;
11831 			}
11832 			else if (!(flags & BMT_NO_INT)) {
11833 				char buf[32];
11834 				const char *out;
11835 
11836 				if (!first) {
11837 					proto_item_append_text(item, ", ");
11838 				}
11839 
11840 				out = hfinfo_number_value_format(hf, buf, (gint32) integer32);
11841 				if ((hf->strings) &&(!(hf->display & BASE_UNIT_STRING))) {
11842 					proto_item_append_text(item, "%s: %s%s", hf->name, out, unit_name_string_get_value((guint32) tmpval, (const unit_name_string*)hf->strings));
11843 				} else {
11844 					proto_item_append_text(item, "%s: %s", hf->name, out);
11845 				}
11846 				first = FALSE;
11847 			}
11848 
11849 			break;
11850 
11851 		case FT_UINT40:
11852 		case FT_UINT48:
11853 		case FT_UINT56:
11854 		case FT_UINT64:
11855 			if (hf->display == BASE_CUSTOM) {
11856 				gchar lbl[ITEM_LABEL_LENGTH];
11857 				const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
11858 
11859 				DISSECTOR_ASSERT(fmtfunc);
11860 				fmtfunc(lbl, tmpval);
11861 				proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
11862 						hf->name, lbl);
11863 				first = FALSE;
11864 			}
11865 			else if (hf->strings) {
11866 				proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
11867 						hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
11868 				first = FALSE;
11869 			}
11870 			else if (!(flags & BMT_NO_INT)) {
11871 				char buf[48];
11872 				const char *out;
11873 
11874 				if (!first) {
11875 					proto_item_append_text(item, ", ");
11876 				}
11877 
11878 				out = hfinfo_number_value_format64(hf, buf, tmpval);
11879 				proto_item_append_text(item, "%s: %s", hf->name, out);
11880 				first = FALSE;
11881 			}
11882 
11883 			break;
11884 
11885 		case FT_INT40:
11886 		case FT_INT48:
11887 		case FT_INT56:
11888 		case FT_INT64:
11889 			if (hf->bitmask) {
11890 				no_of_bits = ws_count_ones(hf->bitmask);
11891 				tmpval = ws_sign_ext64(tmpval, no_of_bits);
11892 			}
11893 			if (hf->display == BASE_CUSTOM) {
11894 				gchar lbl[ITEM_LABEL_LENGTH];
11895 				const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
11896 
11897 				DISSECTOR_ASSERT(fmtfunc);
11898 				fmtfunc(lbl, (gint64) tmpval);
11899 				proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
11900 						hf->name, lbl);
11901 				first = FALSE;
11902 			}
11903 			else if (hf->strings) {
11904 				proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
11905 						hf->name, hf_try_val64_to_str_const((gint64) tmpval, hf, "Unknown"));
11906 				first = FALSE;
11907 			}
11908 			else if (!(flags & BMT_NO_INT)) {
11909 				char buf[48];
11910 				const char *out;
11911 
11912 				if (!first) {
11913 					proto_item_append_text(item, ", ");
11914 				}
11915 
11916 				out = hfinfo_number_value_format64(hf, buf, (gint64) tmpval);
11917 				proto_item_append_text(item, "%s: %s", hf->name, out);
11918 				first = FALSE;
11919 			}
11920 
11921 			break;
11922 
11923 		case FT_BOOLEAN:
11924 			if (hf->strings && !(flags & BMT_NO_TFS)) {
11925 				/* If we have true/false strings, emit full - otherwise messages
11926 				   might look weird */
11927 				const struct true_false_string *tfs =
11928 					(const struct true_false_string *)hf->strings;
11929 
11930 				if (tmpval) {
11931 					proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
11932 							hf->name, tfs->true_string);
11933 					first = FALSE;
11934 				} else if (!(flags & BMT_NO_FALSE)) {
11935 					proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
11936 							hf->name, tfs->false_string);
11937 					first = FALSE;
11938 				}
11939 			} else if (hf->bitmask & value) {
11940 				/* If the flag is set, show the name */
11941 				proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
11942 				first = FALSE;
11943 			}
11944 			break;
11945 		default:
11946 			REPORT_DISSECTOR_BUG("field %s has type %d (%s) not handled in proto_item_add_bitmask_tree()",
11947 					     hf->abbrev,
11948 					     hf->type,
11949 					     ftype_name(hf->type));
11950 			break;
11951 		}
11952 
11953 		fields++;
11954 	}
11955 
11956 	/* XXX: We don't pass the hfi into this function. Perhaps we should,
11957 	 * but then again most dissectors don't set the bitmask field for
11958 	 * the higher level bitmask hfi, so calculate the bitmask from the
11959 	 * fields present. */
11960 	if (item) {
11961 		bit_offset = len*8 - 1 - ws_ilog2(bitmask);
11962 		no_of_bits = ws_ilog2(bitmask) - ws_ctz(bitmask) + 1;
11963 		FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset));
11964 		FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_SIZE(no_of_bits));
11965 	}
11966 	return first;
11967 }
11968 
11969 /* This function will dissect a sequence of bytes that describe a
11970  * bitmask and supply the value of that sequence through a pointer.
11971  * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
11972  * to be dissected.
11973  * This field will form an expansion under which the individual fields of the
11974  * bitmask is dissected and displayed.
11975  * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
11976  *
11977  * fields is an array of pointers to int that lists all the fields of the
11978  * bitmask. These fields can be either of the type FT_BOOLEAN for flags
11979  * or another integer of the same type/size as hf_hdr with a mask specified.
11980  * This array is terminated by a NULL entry.
11981  *
11982  * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
11983  * FT_integer fields that have a value_string attached will have the
11984  * matched string displayed on the expansion line.
11985  */
11986 proto_item *
proto_tree_add_bitmask_ret_uint64(proto_tree * parent_tree,tvbuff_t * tvb,const guint offset,const int hf_hdr,const gint ett,int * const * fields,const guint encoding,guint64 * retval)11987 proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
11988 		       const guint offset, const int hf_hdr,
11989 		       const gint ett, int * const *fields,
11990 		       const guint encoding, guint64 *retval)
11991 {
11992 	return proto_tree_add_bitmask_with_flags_ret_uint64(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT|BMT_NO_TFS, retval);
11993 }
11994 
11995 /* This function will dissect a sequence of bytes that describe a
11996  * bitmask.
11997  * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
11998  * to be dissected.
11999  * This field will form an expansion under which the individual fields of the
12000  * bitmask is dissected and displayed.
12001  * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
12002  *
12003  * fields is an array of pointers to int that lists all the fields of the
12004  * bitmask. These fields can be either of the type FT_BOOLEAN for flags
12005  * or another integer of the same type/size as hf_hdr with a mask specified.
12006  * This array is terminated by a NULL entry.
12007  *
12008  * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
12009  * FT_integer fields that have a value_string attached will have the
12010  * matched string displayed on the expansion line.
12011  */
12012 proto_item *
proto_tree_add_bitmask(proto_tree * parent_tree,tvbuff_t * tvb,const guint offset,const int hf_hdr,const gint ett,int * const * fields,const guint encoding)12013 proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
12014 		       const guint offset, const int hf_hdr,
12015 		       const gint ett, int * const *fields,
12016 		       const guint encoding)
12017 {
12018 	return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT|BMT_NO_TFS);
12019 }
12020 
12021 /* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
12022  * what data is appended to the header.
12023  */
12024 proto_item *
proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree * parent_tree,tvbuff_t * tvb,const guint offset,const int hf_hdr,const gint ett,int * const * fields,const guint encoding,const int flags,guint64 * retval)12025 proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
12026 		const int hf_hdr, const gint ett, int * const *fields, const guint encoding, const int flags,
12027 		guint64 *retval)
12028 {
12029 	proto_item        *item = NULL;
12030 	header_field_info *hf;
12031 	int                len;
12032 	guint64            value;
12033 
12034 	PROTO_REGISTRAR_GET_NTH(hf_hdr,hf);
12035 	DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
12036 	len = ftype_length(hf->type);
12037 	value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
12038 
12039 	if (parent_tree) {
12040 		item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
12041 		proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
12042 		    flags, FALSE, FALSE, NULL, value);
12043 	}
12044 
12045 	*retval = value;
12046 	if (hf->bitmask) {
12047 		/* Mask out irrelevant portions */
12048 		*retval &= hf->bitmask;
12049 		/* Shift bits */
12050 		*retval >>= hfinfo_bitshift(hf);
12051 	}
12052 
12053 	return item;
12054 }
12055 
12056 /* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
12057  * what data is appended to the header.
12058  */
12059 proto_item *
proto_tree_add_bitmask_with_flags(proto_tree * parent_tree,tvbuff_t * tvb,const guint offset,const int hf_hdr,const gint ett,int * const * fields,const guint encoding,const int flags)12060 proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
12061 		const int hf_hdr, const gint ett, int * const *fields, const guint encoding, const int flags)
12062 {
12063 	proto_item        *item = NULL;
12064 	header_field_info *hf;
12065 	int                len;
12066 	guint64            value;
12067 
12068 	PROTO_REGISTRAR_GET_NTH(hf_hdr,hf);
12069 	DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
12070 
12071 	if (parent_tree) {
12072 		len = ftype_length(hf->type);
12073 		item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
12074 		value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
12075 		proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
12076 		    flags, FALSE, FALSE, NULL, value);
12077 	}
12078 
12079 	return item;
12080 }
12081 
12082 /* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
12083    can't be retrieved directly from tvb) */
12084 proto_item *
proto_tree_add_bitmask_value(proto_tree * parent_tree,tvbuff_t * tvb,const guint offset,const int hf_hdr,const gint ett,int * const * fields,const guint64 value)12085 proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
12086 		const int hf_hdr, const gint ett, int * const *fields, const guint64 value)
12087 {
12088 	return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
12089 						hf_hdr, ett, fields, value, BMT_NO_INT|BMT_NO_TFS);
12090 }
12091 
12092 /* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
12093 WS_DLL_PUBLIC proto_item *
proto_tree_add_bitmask_value_with_flags(proto_tree * parent_tree,tvbuff_t * tvb,const guint offset,const int hf_hdr,const gint ett,int * const * fields,const guint64 value,const int flags)12094 proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
12095 		const int hf_hdr, const gint ett, int * const *fields, const guint64 value, const int flags)
12096 {
12097 	proto_item        *item = NULL;
12098 	header_field_info *hf;
12099 	int                len;
12100 
12101 	PROTO_REGISTRAR_GET_NTH(hf_hdr,hf);
12102 	DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
12103 	/* the proto_tree_add_uint/_uint64() calls below
12104 	   will fail if tvb==NULL and len!=0 */
12105 	len = tvb ? ftype_length(hf->type) : 0;
12106 
12107 	if (parent_tree) {
12108 		if (len <= 4)
12109 			item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (guint32)value);
12110 		else
12111 			item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
12112 
12113 		proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
12114 		    flags, FALSE, FALSE, NULL, value);
12115 	}
12116 
12117 	return item;
12118 }
12119 
12120 /* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
12121 void
proto_tree_add_bitmask_list(proto_tree * tree,tvbuff_t * tvb,const guint offset,const int len,int * const * fields,const guint encoding)12122 proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const guint offset,
12123 								const int len, int * const *fields, const guint encoding)
12124 {
12125 	guint64 value;
12126 
12127 	if (tree) {
12128 		value = get_uint64_value(tree, tvb, offset, len, encoding);
12129 		proto_item_add_bitmask_tree(NULL, tvb, offset, len, -1, fields,
12130 		    BMT_NO_APPEND, FALSE, TRUE, tree, value);
12131 	}
12132 }
12133 
12134 WS_DLL_PUBLIC void
proto_tree_add_bitmask_list_value(proto_tree * tree,tvbuff_t * tvb,const guint offset,const int len,int * const * fields,const guint64 value)12135 proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const guint offset,
12136 								const int len, int * const *fields, const guint64 value)
12137 {
12138 	if (tree) {
12139 		proto_item_add_bitmask_tree(NULL, tvb, offset, len, -1, fields,
12140 		    BMT_NO_APPEND, FALSE, TRUE, tree, value);
12141 	}
12142 }
12143 
12144 
12145 /* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
12146  * This is intended to support bitmask fields whose lengths can vary, perhaps
12147  * as the underlying standard evolves over time.
12148  * With this API there is the possibility of being called to display more or
12149  * less data than the dissector was coded to support.
12150  * In such cases, it is assumed that bitmasks are extended on the MSb end.
12151  * Thus when presented with "too much" or "too little" data, MSbits will be
12152  * ignored or MSfields sacrificed.
12153  *
12154  * Only fields for which all defined bits are available are displayed.
12155  */
12156 proto_item *
proto_tree_add_bitmask_len(proto_tree * parent_tree,tvbuff_t * tvb,const guint offset,const guint len,const int hf_hdr,const gint ett,int * const * fields,struct expert_field * exp,const guint encoding)12157 proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
12158 		       const guint offset,  const guint len, const int hf_hdr,
12159 		       const gint ett, int * const *fields, struct expert_field* exp,
12160 		       const guint encoding)
12161 {
12162 	proto_item        *item = NULL;
12163 	header_field_info *hf;
12164 	guint   decodable_len;
12165 	guint   decodable_offset;
12166 	guint32 decodable_value;
12167 	guint64 value;
12168 
12169 	PROTO_REGISTRAR_GET_NTH(hf_hdr, hf);
12170 	DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
12171 
12172 	decodable_offset = offset;
12173 	decodable_len = MIN(len, (guint) ftype_length(hf->type));
12174 
12175 	/* If we are ftype_length-limited,
12176 	 * make sure we decode as many LSBs as possible.
12177 	 */
12178 	if (encoding == ENC_BIG_ENDIAN) {
12179 		decodable_offset += (len - decodable_len);
12180 	}
12181 
12182 	if (parent_tree) {
12183 		decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
12184 						 decodable_len, encoding);
12185 
12186 		/* The root item covers all the bytes even if we can't decode them all */
12187 		item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
12188 					   decodable_value);
12189 	}
12190 
12191 	if (decodable_len < len) {
12192 		/* Dissector likely requires updating for new protocol revision */
12193 		expert_add_info_format(NULL, item, exp,
12194 				       "Only least-significant %d of %d bytes decoded",
12195 				       decodable_len, len);
12196 	}
12197 
12198 	if (item) {
12199 		value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
12200 		proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
12201 		    ett, fields, BMT_NO_INT|BMT_NO_TFS, FALSE, FALSE, NULL, value);
12202 	}
12203 
12204 	return item;
12205 }
12206 
12207 /* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
12208 proto_item *
proto_tree_add_bitmask_text(proto_tree * parent_tree,tvbuff_t * tvb,const guint offset,const guint len,const char * name,const char * fallback,const gint ett,int * const * fields,const guint encoding,const int flags)12209 proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
12210 			    const guint offset, const guint len,
12211 			    const char *name, const char *fallback,
12212 			    const gint ett, int * const *fields,
12213 			    const guint encoding, const int flags)
12214 {
12215 	proto_item *item = NULL;
12216 	guint64     value;
12217 
12218 	if (parent_tree) {
12219 		item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
12220 		value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
12221 		if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
12222 		    flags, TRUE, FALSE, NULL, value) && fallback) {
12223 			/* Still at first item - append 'fallback' text if any */
12224 			proto_item_append_text(item, "%s", fallback);
12225 		}
12226 	}
12227 
12228 	return item;
12229 }
12230 
12231 proto_item *
proto_tree_add_bits_item(proto_tree * tree,const int hfindex,tvbuff_t * tvb,const guint bit_offset,const gint no_of_bits,const guint encoding)12232 proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
12233 			 const guint bit_offset, const gint no_of_bits,
12234 			 const guint encoding)
12235 {
12236 	header_field_info *hfinfo;
12237 	gint		   octet_length;
12238 	gint		   octet_offset;
12239 
12240 	PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
12241 
12242 	octet_length = (no_of_bits + 7) >> 3;
12243 	octet_offset = bit_offset >> 3;
12244 	test_length(hfinfo, tvb, octet_offset, octet_length, encoding);
12245 
12246 	/* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
12247 	 * but only after doing a bunch more work (which we can, in the common
12248 	 * case, shortcut here).
12249 	 */
12250 	CHECK_FOR_NULL_TREE(tree);
12251 	TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
12252 
12253 	return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL, encoding);
12254 }
12255 
12256 /*
12257  * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
12258  * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
12259  * Offset should be given in bits from the start of the tvb.
12260  */
12261 
12262 static proto_item *
_proto_tree_add_bits_ret_val(proto_tree * tree,const int hfindex,tvbuff_t * tvb,const guint bit_offset,const gint no_of_bits,guint64 * return_value,const guint encoding)12263 _proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
12264 			    const guint bit_offset, const gint no_of_bits,
12265 			    guint64 *return_value, const guint encoding)
12266 {
12267 	gint     offset;
12268 	guint    length;
12269 	guint8   tot_no_bits;
12270 	char    *bf_str;
12271 	char     lbl_str[ITEM_LABEL_LENGTH];
12272 	guint64  value = 0;
12273 	guint8  *bytes = NULL;
12274 	size_t bytes_length = 0;
12275 
12276 	proto_item        *pi;
12277 	header_field_info *hf_field;
12278 
12279 	const true_false_string *tfstring;
12280 
12281 	/* We can't fake it just yet. We have to fill in the 'return_value' parameter */
12282 	PROTO_REGISTRAR_GET_NTH(hfindex, hf_field);
12283 
12284 	if (hf_field->bitmask != 0) {
12285 		REPORT_DISSECTOR_BUG("Incompatible use of proto_tree_add_bits_ret_val"
12286 				     " with field '%s' (%s) with bitmask != 0",
12287 				     hf_field->abbrev, hf_field->name);
12288 	}
12289 
12290 	if (no_of_bits == 0) {
12291 		REPORT_DISSECTOR_BUG("field %s passed to proto_tree_add_bits_ret_val() has a bit width of 0",
12292 				     hf_field->abbrev);
12293 	}
12294 
12295 	/* Byte align offset */
12296 	offset = bit_offset>>3;
12297 
12298 	/*
12299 	 * Calculate the number of octets used to hold the bits
12300 	 */
12301 	tot_no_bits = ((bit_offset&0x7) + no_of_bits);
12302 	length = (tot_no_bits + 7) >> 3;
12303 
12304 	if (no_of_bits < 65) {
12305 		value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
12306 	} else if (hf_field->type != FT_BYTES) {
12307 		REPORT_DISSECTOR_BUG("field %s passed to proto_tree_add_bits_ret_val() has a bit width of %u > 65",
12308 				     hf_field->abbrev, no_of_bits);
12309 		return NULL;
12310 	}
12311 
12312 	/* Sign extend for signed types */
12313 	switch (hf_field->type) {
12314 		case FT_INT8:
12315 		case FT_INT16:
12316 		case FT_INT24:
12317 		case FT_INT32:
12318 		case FT_INT40:
12319 		case FT_INT48:
12320 		case FT_INT56:
12321 		case FT_INT64:
12322 			value = ws_sign_ext64(value, no_of_bits);
12323 			break;
12324 
12325 		default:
12326 			break;
12327 	}
12328 
12329 	if (return_value) {
12330 		*return_value = value;
12331 	}
12332 
12333 	/* Coast clear. Try and fake it */
12334 	CHECK_FOR_NULL_TREE(tree);
12335 	TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
12336 
12337 	bf_str = decode_bits_in_field(PNODE_POOL(tree), bit_offset, no_of_bits, value, encoding);
12338 
12339 	switch (hf_field->type) {
12340 	case FT_BOOLEAN:
12341 		/* Boolean field */
12342 		tfstring = &tfs_true_false;
12343 		if (hf_field->strings)
12344 			tfstring = (const true_false_string *)hf_field->strings;
12345 		return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, (guint32)value,
12346 			"%s = %s: %s",
12347 			bf_str, hf_field->name, tfs_get_string(!!value, tfstring));
12348 		break;
12349 
12350 	case FT_CHAR:
12351 		pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (guint32)value);
12352 		fill_label_char(PITEM_FINFO(pi), lbl_str);
12353 		break;
12354 
12355 	case FT_UINT8:
12356 	case FT_UINT16:
12357 	case FT_UINT24:
12358 	case FT_UINT32:
12359 		pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (guint32)value);
12360 		fill_label_number(PITEM_FINFO(pi), lbl_str, FALSE);
12361 		break;
12362 
12363 	case FT_INT8:
12364 	case FT_INT16:
12365 	case FT_INT24:
12366 	case FT_INT32:
12367 		pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (gint32)value);
12368 		fill_label_number(PITEM_FINFO(pi), lbl_str, TRUE);
12369 		break;
12370 
12371 	case FT_UINT40:
12372 	case FT_UINT48:
12373 	case FT_UINT56:
12374 	case FT_UINT64:
12375 		pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
12376 		fill_label_number64(PITEM_FINFO(pi), lbl_str, FALSE);
12377 		break;
12378 
12379 	case FT_INT40:
12380 	case FT_INT48:
12381 	case FT_INT56:
12382 	case FT_INT64:
12383 		pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (gint64)value);
12384 		fill_label_number64(PITEM_FINFO(pi), lbl_str, TRUE);
12385 		break;
12386 
12387 	case FT_BYTES:
12388 		bytes = tvb_get_bits_array(PNODE_POOL(tree), tvb, bit_offset, no_of_bits, &bytes_length, encoding);
12389 		pi = proto_tree_add_bytes_with_length(tree, hfindex, tvb, offset, length, bytes, (gint) bytes_length);
12390 		proto_item_fill_label(PITEM_FINFO(pi), lbl_str);
12391 		proto_item_set_text(pi, "%s", lbl_str);
12392 		return pi;
12393 		break;
12394 
12395 	default:
12396 		REPORT_DISSECTOR_BUG("field %s has type %d (%s) not handled in proto_tree_add_bits_ret_val()",
12397 				     hf_field->abbrev,
12398 				     hf_field->type,
12399 				     ftype_name(hf_field->type));
12400 		return NULL;
12401 		break;
12402 	}
12403 
12404 	proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
12405 	return pi;
12406 }
12407 
12408 proto_item *
proto_tree_add_split_bits_item_ret_val(proto_tree * tree,const int hfindex,tvbuff_t * tvb,const guint bit_offset,const crumb_spec_t * crumb_spec,guint64 * return_value)12409 proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
12410 				       const guint bit_offset, const crumb_spec_t *crumb_spec,
12411 				       guint64 *return_value)
12412 {
12413 	proto_item *pi;
12414 	gint        no_of_bits;
12415 	gint        octet_offset;
12416 	guint       mask_initial_bit_offset;
12417 	guint       mask_greatest_bit_offset;
12418 	guint       octet_length;
12419 	guint8      i;
12420 	char        bf_str[256];
12421 	char        lbl_str[ITEM_LABEL_LENGTH];
12422 	guint64     value;
12423 	guint64     composite_bitmask;
12424 	guint64     composite_bitmap;
12425 
12426 	header_field_info       *hf_field;
12427 	const true_false_string *tfstring;
12428 
12429 	/* We can't fake it just yet. We have to fill in the 'return_value' parameter */
12430 	PROTO_REGISTRAR_GET_NTH(hfindex, hf_field);
12431 
12432 	if (hf_field->bitmask != 0) {
12433 		REPORT_DISSECTOR_BUG("Incompatible use of proto_tree_add_split_bits_item_ret_val"
12434 				     " with field '%s' (%s) with bitmask != 0",
12435 				     hf_field->abbrev, hf_field->name);
12436 	}
12437 
12438 	mask_initial_bit_offset = bit_offset % 8;
12439 
12440 	no_of_bits = 0;
12441 	value      = 0;
12442 	i          = 0;
12443 	mask_greatest_bit_offset = 0;
12444 	composite_bitmask        = 0;
12445 	composite_bitmap         = 0;
12446 
12447 	while (crumb_spec[i].crumb_bit_length != 0) {
12448 		guint64 crumb_mask, crumb_value;
12449 		guint8	crumb_end_bit_offset;
12450 
12451 		crumb_value = tvb_get_bits64(tvb,
12452 					     bit_offset + crumb_spec[i].crumb_bit_offset,
12453 					     crumb_spec[i].crumb_bit_length,
12454 					     ENC_BIG_ENDIAN);
12455 		value      += crumb_value;
12456 		no_of_bits += crumb_spec[i].crumb_bit_length;
12457 		DISSECTOR_ASSERT_HINT(no_of_bits <= 64, "a value larger than 64 bits cannot be represented");
12458 
12459 		/* The bitmask is 64 bit, left-aligned, starting at the first bit of the
12460 		   octet containing the initial offset.
12461 		   If the mask is beyond 32 bits, then give up on bit map display.
12462 		   This could be improved in future, probably showing a table
12463 		   of 32 or 64 bits per row */
12464 		if (mask_greatest_bit_offset < 32) {
12465 			crumb_end_bit_offset = mask_initial_bit_offset
12466 				+ crumb_spec[i].crumb_bit_offset
12467 				+ crumb_spec[i].crumb_bit_length;
12468 			crumb_mask = (G_GUINT64_CONSTANT(1) << crumb_spec[i].crumb_bit_length) - 1;
12469 
12470 			if (crumb_end_bit_offset > mask_greatest_bit_offset) {
12471 				mask_greatest_bit_offset = crumb_end_bit_offset;
12472 			}
12473 			/* Currently the bitmap of the crumbs are only shown if
12474 			 * smaller than 32 bits. Do not bother calculating the
12475 			 * mask if it is larger than that. */
12476 			if (crumb_end_bit_offset <= 32) {
12477 				composite_bitmask |= (crumb_mask  << (64 - crumb_end_bit_offset));
12478 				composite_bitmap  |= (crumb_value << (64 - crumb_end_bit_offset));
12479 			}
12480 		}
12481 		/* Shift left for the next segment */
12482 		value <<= crumb_spec[++i].crumb_bit_length;
12483 	}
12484 
12485 	/* Sign extend for signed types */
12486 	switch (hf_field->type) {
12487 		case FT_INT8:
12488 		case FT_INT16:
12489 		case FT_INT24:
12490 		case FT_INT32:
12491 		case FT_INT40:
12492 		case FT_INT48:
12493 		case FT_INT56:
12494 		case FT_INT64:
12495 			value = ws_sign_ext64(value, no_of_bits);
12496 			break;
12497 		default:
12498 			break;
12499 	}
12500 
12501 	if (return_value) {
12502 		*return_value = value;
12503 	}
12504 
12505 	/* Coast clear. Try and fake it */
12506 	CHECK_FOR_NULL_TREE(tree);
12507 	TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
12508 
12509 	/* initialise the format string */
12510 	bf_str[0] = '\0';
12511 
12512 	octet_offset = bit_offset >> 3;
12513 
12514 	/* Round up mask length to nearest octet */
12515 	octet_length = ((mask_greatest_bit_offset + 7) >> 3);
12516 	mask_greatest_bit_offset = octet_length << 3;
12517 
12518 	/* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
12519 	   It would be a useful enhancement to eliminate this restriction. */
12520 	if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
12521 		other_decode_bitfield_value(bf_str,
12522 					    (guint32)(composite_bitmap  >> (64 - mask_greatest_bit_offset)),
12523 					    (guint32)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
12524 					    mask_greatest_bit_offset);
12525 	} else {
12526 		/* If the bitmask is too large, try to describe its contents. */
12527 		g_snprintf(bf_str, sizeof(bf_str), "%d bits", no_of_bits);
12528 	}
12529 
12530 	switch (hf_field->type) {
12531 	case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
12532 		/* Boolean field */
12533 		tfstring = &tfs_true_false;
12534 		if (hf_field->strings)
12535 			tfstring = (const true_false_string *) hf_field->strings;
12536 		return proto_tree_add_boolean_format(tree, hfindex,
12537 						     tvb, octet_offset, octet_length, (guint32)value,
12538 						     "%s = %s: %s",
12539 						     bf_str, hf_field->name, tfs_get_string(!!value, tfstring));
12540 		break;
12541 
12542 	case FT_CHAR:
12543 		pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (guint32)value);
12544 		fill_label_char(PITEM_FINFO(pi), lbl_str);
12545 		break;
12546 
12547 	case FT_UINT8:
12548 	case FT_UINT16:
12549 	case FT_UINT24:
12550 	case FT_UINT32:
12551 		pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (guint32)value);
12552 		fill_label_number(PITEM_FINFO(pi), lbl_str, FALSE);
12553 		break;
12554 
12555 	case FT_INT8:
12556 	case FT_INT16:
12557 	case FT_INT24:
12558 	case FT_INT32:
12559 		pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (gint32)value);
12560 		fill_label_number(PITEM_FINFO(pi), lbl_str, TRUE);
12561 		break;
12562 
12563 	case FT_UINT40:
12564 	case FT_UINT48:
12565 	case FT_UINT56:
12566 	case FT_UINT64:
12567 		pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
12568 		fill_label_number64(PITEM_FINFO(pi), lbl_str, FALSE);
12569 		break;
12570 
12571 	case FT_INT40:
12572 	case FT_INT48:
12573 	case FT_INT56:
12574 	case FT_INT64:
12575 		pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (gint64)value);
12576 		fill_label_number64(PITEM_FINFO(pi), lbl_str, TRUE);
12577 		break;
12578 
12579 	default:
12580 		REPORT_DISSECTOR_BUG("field %s has type %d (%s) not handled in proto_tree_add_split_bits_item_ret_val()",
12581 				     hf_field->abbrev,
12582 				     hf_field->type,
12583 				     ftype_name(hf_field->type));
12584 		return NULL;
12585 		break;
12586 	}
12587 	proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
12588 	return pi;
12589 }
12590 
12591 void
proto_tree_add_split_bits_crumb(proto_tree * tree,const int hfindex,tvbuff_t * tvb,const guint bit_offset,const crumb_spec_t * crumb_spec,guint16 crumb_index)12592 proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const guint bit_offset,
12593 				const crumb_spec_t *crumb_spec, guint16 crumb_index)
12594 {
12595 	header_field_info *hfinfo;
12596 	gint start = bit_offset >> 3;
12597 	gint length = ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1;
12598 
12599 	/* We have to duplicate this length check from proto_tree_add_text_internal in order to check for a null tree
12600 	 * so that we can use the tree's memory scope in calculating the string */
12601 	if (length == -1) {
12602 		tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
12603 	} else {
12604 		tvb_ensure_bytes_exist(tvb, start, length);
12605 	}
12606 	if (!tree) return;
12607 
12608 	PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
12609 	proto_tree_add_text_internal(tree, tvb, start, length,
12610 			    "%s crumb %d of %s (decoded above)",
12611 			    decode_bits_in_field(PNODE_POOL(tree), bit_offset, crumb_spec[crumb_index].crumb_bit_length,
12612 						 tvb_get_bits(tvb,
12613 							      bit_offset,
12614 							      crumb_spec[crumb_index].crumb_bit_length,
12615 							      ENC_BIG_ENDIAN),
12616 						 ENC_BIG_ENDIAN),
12617 			    crumb_index,
12618 			    hfinfo->name);
12619 }
12620 
12621 proto_item *
proto_tree_add_bits_ret_val(proto_tree * tree,const int hfindex,tvbuff_t * tvb,const guint bit_offset,const gint no_of_bits,guint64 * return_value,const guint encoding)12622 proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
12623 			    const guint bit_offset, const gint no_of_bits,
12624 			    guint64 *return_value, const guint encoding)
12625 {
12626 	proto_item *item;
12627 
12628 	if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
12629 						 bit_offset, no_of_bits,
12630 						 return_value, encoding))) {
12631 		FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset));
12632 		FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_SIZE(no_of_bits));
12633 	}
12634 	return item;
12635 }
12636 
12637 static proto_item *
_proto_tree_add_bits_format_value(proto_tree * tree,const int hfindex,tvbuff_t * tvb,const guint bit_offset,const gint no_of_bits,void * value_ptr,const guint encoding,gchar * value_str)12638 _proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
12639 				 tvbuff_t *tvb, const guint bit_offset,
12640 				 const gint no_of_bits, void *value_ptr,
12641 				 const guint encoding, gchar *value_str)
12642 {
12643 	gint     offset;
12644 	guint    length;
12645 	guint8   tot_no_bits;
12646 	char    *str;
12647 	guint64  value = 0;
12648 	header_field_info *hf_field;
12649 
12650 	/* We do not have to return a value, try to fake it as soon as possible */
12651 	CHECK_FOR_NULL_TREE(tree);
12652 	TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
12653 
12654 	if (hf_field->bitmask != 0) {
12655 		REPORT_DISSECTOR_BUG("Incompatible use of proto_tree_add_bits_format_value"
12656 				     " with field '%s' (%s) with bitmask != 0",
12657 				     hf_field->abbrev, hf_field->name);
12658 	}
12659 
12660 	if (no_of_bits == 0) {
12661 		REPORT_DISSECTOR_BUG("field %s passed to proto_tree_add_bits_format_value() has a bit width of 0",
12662 				     hf_field->abbrev);
12663 	}
12664 
12665 	/* Byte align offset */
12666 	offset = bit_offset>>3;
12667 
12668 	/*
12669 	 * Calculate the number of octets used to hold the bits
12670 	 */
12671 	tot_no_bits = ((bit_offset&0x7) + no_of_bits);
12672 	length      = tot_no_bits>>3;
12673 	/* If we are using part of the next octet, increase length by 1 */
12674 	if (tot_no_bits & 0x07)
12675 		length++;
12676 
12677 	if (no_of_bits < 65) {
12678 		value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
12679 	} else {
12680 		REPORT_DISSECTOR_BUG("field %s passed to proto_tree_add_bits_format_value() has a bit width of %u > 65",
12681 				     hf_field->abbrev, no_of_bits);
12682 		return NULL;
12683 	}
12684 
12685 	str = decode_bits_in_field(PNODE_POOL(tree), bit_offset, no_of_bits, value, encoding);
12686 
12687 	(void) g_strlcat(str, " = ", 256+64);
12688 	(void) g_strlcat(str, hf_field->name, 256+64);
12689 
12690 	/*
12691 	 * This function does not receive an actual value but a dimensionless pointer to that value.
12692 	 * For this reason, the type of the header field is examined in order to determine
12693 	 * what kind of value we should read from this address.
12694 	 * The caller of this function must make sure that for the specific header field type the address of
12695 	 * a compatible value is provided.
12696 	 */
12697 	switch (hf_field->type) {
12698 	case FT_BOOLEAN:
12699 		return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(guint32 *)value_ptr,
12700 						     "%s: %s", str, value_str);
12701 		break;
12702 
12703 	case FT_CHAR:
12704 	case FT_UINT8:
12705 	case FT_UINT16:
12706 	case FT_UINT24:
12707 	case FT_UINT32:
12708 		return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(guint32 *)value_ptr,
12709 						  "%s: %s", str, value_str);
12710 		break;
12711 
12712 	case FT_UINT40:
12713 	case FT_UINT48:
12714 	case FT_UINT56:
12715 	case FT_UINT64:
12716 		return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(guint64 *)value_ptr,
12717 						    "%s: %s", str, value_str);
12718 		break;
12719 
12720 	case FT_INT8:
12721 	case FT_INT16:
12722 	case FT_INT24:
12723 	case FT_INT32:
12724 		return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(gint32 *)value_ptr,
12725 						 "%s: %s", str, value_str);
12726 		break;
12727 
12728 	case FT_INT40:
12729 	case FT_INT48:
12730 	case FT_INT56:
12731 	case FT_INT64:
12732 		return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(gint64 *)value_ptr,
12733 						   "%s: %s", str, value_str);
12734 		break;
12735 
12736 	case FT_FLOAT:
12737 		return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
12738 						   "%s: %s", str, value_str);
12739 		break;
12740 
12741 	default:
12742 		REPORT_DISSECTOR_BUG("field %s has type %d (%s) not handled in proto_tree_add_bits_format_value()",
12743 				     hf_field->abbrev,
12744 				     hf_field->type,
12745 				     ftype_name(hf_field->type));
12746 		return NULL;
12747 		break;
12748 	}
12749 }
12750 
12751 static proto_item *
proto_tree_add_bits_format_value(proto_tree * tree,const int hfindex,tvbuff_t * tvb,const guint bit_offset,const gint no_of_bits,void * value_ptr,const guint encoding,gchar * value_str)12752 proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
12753 				 tvbuff_t *tvb, const guint bit_offset,
12754 				 const gint no_of_bits, void *value_ptr,
12755 				 const guint encoding, gchar *value_str)
12756 {
12757 	proto_item *item;
12758 
12759 	if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
12760 						      tvb, bit_offset, no_of_bits,
12761 						      value_ptr, encoding, value_str))) {
12762 		FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset));
12763 		FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_SIZE(no_of_bits));
12764 	}
12765 	return item;
12766 }
12767 
12768 #define CREATE_VALUE_STRING(tree,dst,format,ap) \
12769 	va_start(ap, format); \
12770 	dst = wmem_strdup_vprintf(PNODE_POOL(tree), format, ap); \
12771 	va_end(ap);
12772 
12773 proto_item *
proto_tree_add_uint_bits_format_value(proto_tree * tree,const int hfindex,tvbuff_t * tvb,const guint bit_offset,const gint no_of_bits,guint32 value,const guint encoding,const char * format,...)12774 proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
12775 				      tvbuff_t *tvb, const guint bit_offset,
12776 				      const gint no_of_bits, guint32 value,
12777 				      const guint encoding,
12778 				      const char *format, ...)
12779 {
12780 	va_list ap;
12781 	gchar  *dst;
12782 	header_field_info *hf_field;
12783 
12784 	CHECK_FOR_NULL_TREE(tree);
12785 
12786 	TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
12787 
12788 	switch (hf_field->type) {
12789 		case FT_UINT8:
12790 		case FT_UINT16:
12791 		case FT_UINT24:
12792 		case FT_UINT32:
12793 			break;
12794 
12795 		default:
12796 			REPORT_DISSECTOR_BUG("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32",
12797 			    hf_field->abbrev);
12798 			return NULL;
12799 			break;
12800 	}
12801 
12802 	CREATE_VALUE_STRING(tree, dst, format, ap);
12803 
12804 	return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
12805 }
12806 
12807 proto_item *
proto_tree_add_uint64_bits_format_value(proto_tree * tree,const int hfindex,tvbuff_t * tvb,const guint bit_offset,const gint no_of_bits,guint64 value,const guint encoding,const char * format,...)12808 proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
12809 				      tvbuff_t *tvb, const guint bit_offset,
12810 				      const gint no_of_bits, guint64 value,
12811 				      const guint encoding,
12812 				      const char *format, ...)
12813 {
12814 	va_list ap;
12815 	gchar  *dst;
12816 	header_field_info *hf_field;
12817 
12818 	CHECK_FOR_NULL_TREE(tree);
12819 
12820 	TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
12821 
12822 	switch (hf_field->type) {
12823 		case FT_UINT40:
12824 		case FT_UINT48:
12825 		case FT_UINT56:
12826 		case FT_UINT64:
12827 			break;
12828 
12829 		default:
12830 			REPORT_DISSECTOR_BUG("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64",
12831 			    hf_field->abbrev);
12832 			return NULL;
12833 			break;
12834 	}
12835 
12836 	CREATE_VALUE_STRING(tree, dst, format, ap);
12837 
12838 	return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
12839 }
12840 
12841 proto_item *
proto_tree_add_float_bits_format_value(proto_tree * tree,const int hfindex,tvbuff_t * tvb,const guint bit_offset,const gint no_of_bits,float value,const guint encoding,const char * format,...)12842 proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
12843 				       tvbuff_t *tvb, const guint bit_offset,
12844 				       const gint no_of_bits, float value,
12845 				       const guint encoding,
12846 				       const char *format, ...)
12847 {
12848 	va_list ap;
12849 	gchar  *dst;
12850 	header_field_info *hf_field;
12851 
12852 	CHECK_FOR_NULL_TREE(tree);
12853 
12854 	TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
12855 
12856 	DISSECTOR_ASSERT_FIELD_TYPE(hf_field, FT_FLOAT);
12857 
12858 	CREATE_VALUE_STRING(tree, dst, format, ap);
12859 
12860 	return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
12861 }
12862 
12863 proto_item *
proto_tree_add_int_bits_format_value(proto_tree * tree,const int hfindex,tvbuff_t * tvb,const guint bit_offset,const gint no_of_bits,gint32 value,const guint encoding,const char * format,...)12864 proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
12865 				     tvbuff_t *tvb, const guint bit_offset,
12866 				     const gint no_of_bits, gint32 value,
12867 	                             const guint encoding,
12868 				     const char *format, ...)
12869 {
12870 	va_list ap;
12871 	gchar  *dst;
12872 	header_field_info *hf_field;
12873 
12874 	CHECK_FOR_NULL_TREE(tree);
12875 
12876 	TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
12877 
12878 	switch (hf_field->type) {
12879 		case FT_INT8:
12880 		case FT_INT16:
12881 		case FT_INT24:
12882 		case FT_INT32:
12883 			break;
12884 
12885 		default:
12886 			REPORT_DISSECTOR_BUG("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32",
12887 			    hf_field->abbrev);
12888 			return NULL;
12889 			break;
12890 	}
12891 
12892 	CREATE_VALUE_STRING(tree, dst, format, ap);
12893 
12894 	return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
12895 }
12896 
12897 proto_item *
proto_tree_add_int64_bits_format_value(proto_tree * tree,const int hfindex,tvbuff_t * tvb,const guint bit_offset,const gint no_of_bits,gint64 value,const guint encoding,const char * format,...)12898 proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
12899 				     tvbuff_t *tvb, const guint bit_offset,
12900 				     const gint no_of_bits, gint64 value,
12901 				     const guint encoding,
12902 				     const char *format, ...)
12903 {
12904 	va_list ap;
12905 	gchar  *dst;
12906 	header_field_info *hf_field;
12907 
12908 	CHECK_FOR_NULL_TREE(tree);
12909 
12910 	TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
12911 
12912 	switch (hf_field->type) {
12913 		case FT_INT40:
12914 		case FT_INT48:
12915 		case FT_INT56:
12916 		case FT_INT64:
12917 			break;
12918 
12919 		default:
12920 			REPORT_DISSECTOR_BUG("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64",
12921 			    hf_field->abbrev);
12922 			return NULL;
12923 			break;
12924 	}
12925 
12926 	CREATE_VALUE_STRING(tree, dst, format, ap);
12927 
12928 	return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
12929 }
12930 
12931 proto_item *
proto_tree_add_boolean_bits_format_value(proto_tree * tree,const int hfindex,tvbuff_t * tvb,const guint bit_offset,const gint no_of_bits,guint32 value,const guint encoding,const char * format,...)12932 proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
12933 					 tvbuff_t *tvb, const guint bit_offset,
12934 					 const gint no_of_bits, guint32 value,
12935 				         const guint encoding,
12936 					 const char *format, ...)
12937 {
12938 	va_list ap;
12939 	gchar  *dst;
12940 	header_field_info *hf_field;
12941 
12942 	CHECK_FOR_NULL_TREE(tree);
12943 
12944 	TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
12945 
12946 	DISSECTOR_ASSERT_FIELD_TYPE(hf_field, FT_BOOLEAN);
12947 
12948 	CREATE_VALUE_STRING(tree, dst, format, ap);
12949 
12950 	return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
12951 }
12952 
12953 proto_item *
proto_tree_add_boolean_bits_format_value64(proto_tree * tree,const int hfindex,tvbuff_t * tvb,const guint bit_offset,const gint no_of_bits,guint64 value,const guint encoding,const char * format,...)12954 proto_tree_add_boolean_bits_format_value64(proto_tree *tree, const int hfindex,
12955 					 tvbuff_t *tvb, const guint bit_offset,
12956 					 const gint no_of_bits, guint64 value,
12957 				         const guint encoding,
12958 					 const char *format, ...)
12959 {
12960 	va_list ap;
12961 	gchar  *dst;
12962 	header_field_info *hf_field;
12963 
12964 	CHECK_FOR_NULL_TREE(tree);
12965 
12966 	TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
12967 
12968 	DISSECTOR_ASSERT_FIELD_TYPE(hf_field, FT_BOOLEAN);
12969 
12970 	CREATE_VALUE_STRING(tree, dst, format, ap);
12971 
12972 	return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
12973 }
12974 
12975 proto_item *
proto_tree_add_ts_23_038_7bits_packed_item(proto_tree * tree,const int hfindex,tvbuff_t * tvb,const guint bit_offset,const gint no_of_chars)12976 proto_tree_add_ts_23_038_7bits_packed_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
12977 	const guint bit_offset, const gint no_of_chars)
12978 {
12979 	proto_item	  *pi;
12980 	header_field_info *hfinfo;
12981 	gint		   byte_length;
12982 	gint		   byte_offset;
12983 	gchar		  *string;
12984 
12985 	CHECK_FOR_NULL_TREE(tree);
12986 
12987 	TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
12988 
12989 	DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_STRING);
12990 
12991 	byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
12992 	byte_offset = bit_offset >> 3;
12993 
12994 	string = tvb_get_ts_23_038_7bits_string_packed(PNODE_POOL(tree), tvb, bit_offset, no_of_chars);
12995 
12996 	if (hfinfo->display == STR_UNICODE) {
12997 		DISSECTOR_ASSERT(g_utf8_validate(string, -1, NULL));
12998 	}
12999 
13000 	pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
13001 	DISSECTOR_ASSERT(byte_length >= 0);
13002 	proto_tree_set_string(PNODE_FINFO(pi), string);
13003 
13004 	return pi;
13005 }
13006 
13007 proto_item *
proto_tree_add_ascii_7bits_item(proto_tree * tree,const int hfindex,tvbuff_t * tvb,const guint bit_offset,const gint no_of_chars)13008 proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13009 	const guint bit_offset, const gint no_of_chars)
13010 {
13011 	proto_item	  *pi;
13012 	header_field_info *hfinfo;
13013 	gint		   byte_length;
13014 	gint		   byte_offset;
13015 	gchar		  *string;
13016 
13017 	CHECK_FOR_NULL_TREE(tree);
13018 
13019 	TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
13020 
13021 	DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_STRING);
13022 
13023 	byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
13024 	byte_offset = bit_offset >> 3;
13025 
13026 	string = tvb_get_ascii_7bits_string(PNODE_POOL(tree), tvb, bit_offset, no_of_chars);
13027 
13028 	if (hfinfo->display == STR_UNICODE) {
13029 		DISSECTOR_ASSERT(g_utf8_validate(string, -1, NULL));
13030 	}
13031 
13032 	pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
13033 	DISSECTOR_ASSERT(byte_length >= 0);
13034 	proto_tree_set_string(PNODE_FINFO(pi), string);
13035 
13036 	return pi;
13037 }
13038 
13039 const value_string proto_checksum_vals[] = {
13040 	{ PROTO_CHECKSUM_E_BAD,        "Bad"  },
13041 	{ PROTO_CHECKSUM_E_GOOD,       "Good" },
13042 	{ PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
13043 	{ PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
13044 	{ PROTO_CHECKSUM_E_ILLEGAL,    "Illegal" },
13045 
13046 	{ 0,        NULL }
13047 };
13048 
13049 proto_item *
proto_tree_add_checksum(proto_tree * tree,tvbuff_t * tvb,const guint offset,const int hf_checksum,const int hf_checksum_status,struct expert_field * bad_checksum_expert,packet_info * pinfo,guint32 computed_checksum,const guint encoding,const guint flags)13050 proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const guint offset,
13051 		const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
13052 		packet_info *pinfo, guint32 computed_checksum, const guint encoding, const guint flags)
13053 {
13054 	header_field_info *hfinfo = proto_registrar_get_nth(hf_checksum);
13055 	guint32 checksum;
13056 	guint32 len;
13057 	proto_item* ti = NULL;
13058 	proto_item* ti2;
13059 	gboolean incorrect_checksum = TRUE;
13060 
13061 	DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
13062 
13063 	switch (hfinfo->type) {
13064 	case FT_UINT8:
13065 		len = 1;
13066 		break;
13067 	case FT_UINT16:
13068 		len = 2;
13069 		break;
13070 	case FT_UINT24:
13071 		len = 3;
13072 		break;
13073 	case FT_UINT32:
13074 		len = 4;
13075 		break;
13076 	default:
13077 		REPORT_DISSECTOR_BUG("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32",
13078 		    hfinfo->abbrev);
13079 	}
13080 
13081 	if (flags & PROTO_CHECKSUM_NOT_PRESENT) {
13082 		ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, len, 0, "[missing]");
13083 		proto_item_set_generated(ti);
13084 		if (hf_checksum_status != -1) {
13085 			ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, len, PROTO_CHECKSUM_E_NOT_PRESENT);
13086 			proto_item_set_generated(ti2);
13087 		}
13088 		return ti;
13089 	}
13090 
13091 	if (flags & PROTO_CHECKSUM_GENERATED) {
13092 		ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, len, computed_checksum);
13093 		proto_item_set_generated(ti);
13094 	} else {
13095 		ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
13096 		if (flags & PROTO_CHECKSUM_VERIFY) {
13097 			if (flags & (PROTO_CHECKSUM_IN_CKSUM|PROTO_CHECKSUM_ZERO)) {
13098 				if (computed_checksum == 0) {
13099 					proto_item_append_text(ti, " [correct]");
13100 					if (hf_checksum_status != -1) {
13101 						ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
13102 						proto_item_set_generated(ti2);
13103 					}
13104 					incorrect_checksum = FALSE;
13105 				} else if (flags & PROTO_CHECKSUM_IN_CKSUM) {
13106 					computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
13107 				}
13108 			} else {
13109 				if (checksum == computed_checksum) {
13110 					proto_item_append_text(ti, " [correct]");
13111 					if (hf_checksum_status != -1) {
13112 						ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
13113 						proto_item_set_generated(ti2);
13114 					}
13115 					incorrect_checksum = FALSE;
13116 				}
13117 			}
13118 
13119 			if (incorrect_checksum) {
13120 				if (hf_checksum_status != -1) {
13121 					ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
13122 					proto_item_set_generated(ti2);
13123 				}
13124 				if (flags & PROTO_CHECKSUM_ZERO) {
13125 					proto_item_append_text(ti, " [incorrect]");
13126 					if (bad_checksum_expert != NULL)
13127 						expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
13128 				} else {
13129 					proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
13130 					if (bad_checksum_expert != NULL)
13131 						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);
13132 				}
13133 			}
13134 		} else {
13135 			if (hf_checksum_status != -1) {
13136 				proto_item_append_text(ti, " [unverified]");
13137 				ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
13138 				proto_item_set_generated(ti2);
13139 			}
13140 		}
13141 	}
13142 
13143 	return ti;
13144 }
13145 
13146 guchar
proto_check_field_name(const gchar * field_name)13147 proto_check_field_name(const gchar *field_name)
13148 {
13149 	const char *p = field_name;
13150 	guchar c = '.', lastc;
13151 
13152 	do {
13153 		lastc = c;
13154 		c = *(p++);
13155 		/* Leading '.' or substring ".." are disallowed. */
13156 		if (c == '.' && lastc == '.') {
13157 			break;
13158 		}
13159 	} while (fld_abbrev_chars[c]);
13160 
13161 	/* Trailing '.' is disallowed. */
13162 	if (lastc == '.') {
13163 		return '.';
13164 	}
13165 	return c;
13166 }
13167 
13168 gboolean
tree_expanded(int tree_type)13169 tree_expanded(int tree_type)
13170 {
13171 	if (tree_type == -1) {
13172 		return FALSE;
13173 	}
13174 	ws_assert(tree_type >= 0 && tree_type < num_tree_types);
13175 	return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
13176 }
13177 
13178 void
tree_expanded_set(int tree_type,gboolean value)13179 tree_expanded_set(int tree_type, gboolean value)
13180 {
13181 	ws_assert(tree_type >= 0 && tree_type < num_tree_types);
13182 
13183 	if (value)
13184 		tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
13185 	else
13186 		tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
13187 }
13188 
13189 /*
13190  * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
13191  *
13192  * Local variables:
13193  * c-basic-offset: 8
13194  * tab-width: 8
13195  * indent-tabs-mode: t
13196  * End:
13197  *
13198  * vi: set shiftwidth=8 tabstop=8 noexpandtab:
13199  * :indentSize=8:tabSize=8:noTabs=false:
13200  */
13201