Allow BASE_NONE (with strings conversion) for integral values again.
[metze/wireshark/wip.git] / epan / proto.c
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  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21  */
22
23 #include "config.h"
24
25 #include <stdio.h>
26 #include <string.h>
27 #include <glib.h>
28 #include <float.h>
29 #include <errno.h>
30
31 #include <wsutil/bits_ctz.h>
32 #include <wsutil/bits_count_ones.h>
33 #include <wsutil/sign_ext.h>
34
35 #include <ftypes/ftypes-int.h>
36
37 #include "packet.h"
38 #include "exceptions.h"
39 #include "ptvcursor.h"
40 #include "strutil.h"
41 #include "addr_resolv.h"
42 #include "address_types.h"
43 #include "oids.h"
44 #include "proto.h"
45 #include "epan_dissect.h"
46 #include "tvbuff.h"
47 #include "wmem/wmem.h"
48 #include "charsets.h"
49 #include "asm_utils.h"
50 #include "column-utils.h"
51 #include "to_str-int.h"
52 #include "to_str.h"
53 #include "osi-utils.h"
54 #include "expert.h"
55 #include "show_exception.h"
56
57 #include <wsutil/plugins.h>
58
59 /* Ptvcursor limits */
60 #define SUBTREE_ONCE_ALLOCATION_NUMBER 8
61 #define SUBTREE_MAX_LEVELS 256
62
63 /* Throw an exception if our tree exceeds these. */
64 /* XXX - These should probably be preferences */
65 #define MAX_TREE_ITEMS (1 * 1000 * 1000)
66 #define MAX_TREE_LEVELS (5 * 100)
67
68 typedef struct __subtree_lvl {
69         gint        cursor_offset;
70         proto_item *it;
71         proto_tree *tree;
72 } subtree_lvl;
73
74 struct ptvcursor {
75         subtree_lvl *pushed_tree;
76         guint8       pushed_tree_index;
77         guint8       pushed_tree_max;
78         proto_tree  *tree;
79         tvbuff_t    *tvb;
80         gint         offset;
81 };
82
83 #define cVALS(x) (const value_string*)(x)
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_AND_FREE(tree, free_block)                  \
90         if (!tree) {                                                    \
91                 free_block;                                             \
92                 return NULL;                                            \
93         }
94
95 /** See inlined comments.
96  @param tree the tree to append this item to
97  @param free_block a code block to call to free resources if this returns
98  @return NULL if 'tree' is null */
99 #define CHECK_FOR_NULL_TREE(tree) \
100         CHECK_FOR_NULL_TREE_AND_FREE(tree, ((void)0))
101
102 /** See inlined comments.
103  @param tree the tree to append this item to
104  @param hfindex field index
105  @param hfinfo header_field
106  @param free_block a code block to call to free resources if this returns
107  @return the header field matching 'hfinfo' */
108 #define TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, free_block) \
109         /* If this item is not referenced we don't have to do much work \
110            at all but we should still return a node so that field items \
111            below this node (think proto_item_add_subtree()) will still  \
112            have somewhere to attach to or else filtering will not work  \
113            (they would be ignored since tree would be NULL).            \
114            DON'T try to fake a node where PTREE_FINFO(tree) is NULL     \
115            since dissectors that want to do proto_item_set_len() or     \
116            other operations that dereference this would crash.          \
117            We fake FT_PROTOCOL unless some clients have requested us    \
118            not to do so.                                                \
119         */                                                              \
120         PTREE_DATA(tree)->count++;                                      \
121         if (PTREE_DATA(tree)->count > MAX_TREE_ITEMS) {                 \
122                 free_block;                                             \
123                 if (getenv("WIRESHARK_ABORT_ON_TOO_MANY_ITEMS") != NULL) \
124                         g_error("More than %d items in the tree -- possible infinite loop", MAX_TREE_ITEMS); \
125                 /* Let the exception handler add items to the tree */   \
126                 PTREE_DATA(tree)->count = 0;                            \
127                 THROW_MESSAGE(DissectorError,                           \
128                         wmem_strdup_printf(wmem_packet_scope(), "More than %d items in the tree -- possible infinite loop", MAX_TREE_ITEMS)); \
129         }                                                               \
130         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);                       \
131         if (!(PTREE_DATA(tree)->visible)) {                             \
132                 if (PTREE_FINFO(tree)) {                                \
133                         if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT)    \
134                             && (hfinfo->type != FT_PROTOCOL ||          \
135                                 PTREE_DATA(tree)->fake_protocols)) {    \
136                                 free_block;                             \
137                                 /* just return tree back to the caller */\
138                                 return tree;                            \
139                         }                                               \
140                 }                                                       \
141         }
142
143 /** See inlined comments.
144  @param tree the tree to append this item to
145  @param hfindex field index
146  @param hfinfo header_field
147  @return the header field matching 'hfinfo' */
148 #define TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo) \
149         TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, ((void)0))
150
151
152 /** See inlined comments.
153  @param pi the created protocol item we're about to return */
154 #define TRY_TO_FAKE_THIS_REPR(pi)       \
155         g_assert(pi);                   \
156         if (!(PTREE_DATA(pi)->visible)) { \
157                 /* If the tree (GUI) isn't visible it's pointless for us to generate the protocol \
158                  * items string representation */ \
159                 return pi; \
160         }
161 /* Same as above but returning void */
162 #define TRY_TO_FAKE_THIS_REPR_VOID(pi)  \
163         if (!pi)                        \
164                 return;                 \
165         if (!(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; \
169         }
170
171 static const char *hf_try_val_to_str(guint32 value, const header_field_info *hfinfo);
172 static const char *hf_try_val64_to_str(guint64 value, const header_field_info *hfinfo);
173 static int hfinfo_container_bitwidth(const header_field_info *hfinfo);
174
175 static void label_mark_truncated(char *label_str, gsize name_pos);
176 #define LABEL_MARK_TRUNCATED_START(label_str) label_mark_truncated(label_str, 0)
177
178 static void fill_label_boolean(field_info *fi, gchar *label_str);
179 static void fill_label_bitfield(field_info *fi, gchar *label_str, gboolean is_signed);
180 static void fill_label_bitfield64(field_info *fi, gchar *label_str, gboolean is_signed);
181 static void fill_label_number(field_info *fi, gchar *label_str, gboolean is_signed);
182 static void fill_label_number64(field_info *fi, gchar *label_str, gboolean is_signed);
183
184 static const char *hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[32], guint32 value);
185 static const char *hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[48], guint64 value);
186 static const char *hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value);
187 static const char *hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[48], guint64 value);
188 static const char *hfinfo_number_value_format(const header_field_info *hfinfo, char buf[32], guint32 value);
189 static const char *hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[48], guint64 value);
190 static const char *hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[32], guint32 value);
191 static const char *hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[48], guint64 value);
192
193 static proto_item *
194 proto_tree_add_node(proto_tree *tree, field_info *fi);
195
196 static void
197 get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start, gint *length,
198                 gint *item_length);
199
200 static gint
201 get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start,
202                 gint length, guint item_length, const gint encoding);
203
204 static field_info *
205 new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
206                const gint start, const gint item_length);
207
208 static proto_item *
209 proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
210                   gint start, gint *length);
211
212 static void
213 proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap);
214 static void
215 proto_tree_set_representation(proto_item *pi, const char *format, va_list ap);
216
217 static void
218 proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data);
219 static void
220 proto_tree_set_bytes(field_info *fi, const guint8* start_ptr, gint length);
221 static void
222 proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, gint offset, gint length);
223 static void
224 proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value);
225 static void
226 proto_tree_set_time(field_info *fi, const nstime_t *value_ptr);
227 static void
228 proto_tree_set_string(field_info *fi, const char* value);
229 static void
230 proto_tree_set_ax25(field_info *fi, const guint8* value);
231 static void
232 proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, gint start);
233 static void
234 proto_tree_set_vines(field_info *fi, const guint8* value);
235 static void
236 proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, gint start);
237 static void
238 proto_tree_set_ether(field_info *fi, const guint8* value);
239 static void
240 proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, gint start);
241 static void
242 proto_tree_set_ipxnet(field_info *fi, guint32 value);
243 static void
244 proto_tree_set_ipv4(field_info *fi, guint32 value);
245 static void
246 proto_tree_set_ipv6(field_info *fi, const guint8* value_ptr);
247 static void
248 proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
249 static void
250 proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
251 static void
252 proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr);
253 static void
254 proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, gint start, const guint encoding);
255 static void
256 proto_tree_set_oid(field_info *fi, const guint8* value_ptr, gint length);
257 static void
258 proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
259 static void
260 proto_tree_set_system_id(field_info *fi, const guint8* value_ptr, gint length);
261 static void
262 proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
263 static void
264 proto_tree_set_boolean(field_info *fi, guint64 value);
265 static void
266 proto_tree_set_float(field_info *fi, float value);
267 static void
268 proto_tree_set_double(field_info *fi, double value);
269 static void
270 proto_tree_set_uint(field_info *fi, guint32 value);
271 static void
272 proto_tree_set_int(field_info *fi, gint32 value);
273 static void
274 proto_tree_set_uint64(field_info *fi, guint64 value);
275 static void
276 proto_tree_set_int64(field_info *fi, gint64 value);
277 static void
278 proto_tree_set_eui64(field_info *fi, const guint64 value);
279 static void
280 proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, gint start, const guint encoding);
281
282 /* Handle type length mismatch (now filterable) expert info */
283 static int proto_type_length_mismatch = -1;
284 static expert_field ei_type_length_mismatch_error = EI_INIT;
285 static expert_field ei_type_length_mismatch_warn = EI_INIT;
286 static void register_type_length_mismatch(void);
287
288 /* Handle number string decoding errors with expert info */
289 static int proto_number_string_decoding_error = -1;
290 static expert_field ei_number_string_decoding_failed_error = EI_INIT;
291 static expert_field ei_number_string_decoding_erange_error = EI_INIT;
292 static void register_number_string_decoding_error(void);
293
294 static int proto_register_field_init(header_field_info *hfinfo, const int parent);
295
296 /* special-case header field used within proto.c */
297 static header_field_info hfi_text_only =
298         { "Text item",  "text", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL };
299 int hf_text_only = -1;
300
301 /* Structure for information about a protocol */
302 struct _protocol {
303         const char *name;               /* long description */
304         const char *short_name;         /* short description */
305         const char *filter_name;        /* name of this protocol in filters */
306         GPtrArray  *fields;             /* fields for this protocol */
307         int         proto_id;           /* field ID for this protocol */
308         gboolean    is_enabled;         /* TRUE if protocol is enabled */
309         gboolean    enabled_by_default; /* TRUE if protocol is enabled by default */
310         gboolean    can_toggle;         /* TRUE if is_enabled can be changed */
311         GList      *heur_list;          /* Heuristic dissectors associated with this protocol */
312 };
313
314 /* List of all protocols */
315 static GList *protocols = NULL;
316
317 /* Deregistered fields */
318 static GPtrArray *deregistered_fields = NULL;
319 static GPtrArray *deregistered_data = NULL;
320
321 /* Contains information about a field when a dissector calls
322  * proto_tree_add_item.  */
323 #define FIELD_INFO_NEW(pool, fi)  fi = wmem_new(pool, field_info)
324 #define FIELD_INFO_FREE(pool, fi) wmem_free(pool, fi)
325
326 /* Contains the space for proto_nodes. */
327 #define PROTO_NODE_INIT(node)                   \
328         node->first_child = NULL;               \
329         node->last_child = NULL;                \
330         node->next = NULL;
331
332 #define PROTO_NODE_FREE(pool, node)                     \
333         wmem_free(pool, node)
334
335 /* String space for protocol and field items for the GUI */
336 #define ITEM_LABEL_NEW(pool, il)                        \
337         il = wmem_new(pool, item_label_t);
338 #define ITEM_LABEL_FREE(pool, il)                       \
339         wmem_free(pool, il);
340
341 #define PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)                                                \
342         if((guint)hfindex >= gpa_hfinfo.len && getenv("WIRESHARK_ABORT_ON_DISSECTOR_BUG"))      \
343                 g_error("Unregistered hf! index=%d", hfindex);                                  \
344         DISSECTOR_ASSERT_HINT((guint)hfindex < gpa_hfinfo.len, "Unregistered hf!");     \
345         DISSECTOR_ASSERT_HINT(gpa_hfinfo.hfi[hfindex] != NULL, "Unregistered hf!");     \
346         hfinfo = gpa_hfinfo.hfi[hfindex];
347
348 /* List which stores protocols and fields that have been registered */
349 typedef struct _gpa_hfinfo_t {
350         guint32             len;
351         guint32             allocated_len;
352         header_field_info **hfi;
353 } gpa_hfinfo_t;
354
355 static gpa_hfinfo_t gpa_hfinfo;
356
357 /* Hash table of abbreviations and IDs */
358 static GHashTable *gpa_name_map = NULL;
359 static header_field_info *same_name_hfinfo;
360 /*
361  * We're called repeatedly with the same field name when sorting a column.
362  * Cache our last gpa_name_map hit for faster lookups.
363  */
364 static char *last_field_name = NULL;
365 static header_field_info *last_hfinfo;
366
367 static void save_same_name_hfinfo(gpointer data)
368 {
369         same_name_hfinfo = (header_field_info*)data;
370 }
371
372 /* Cached value for VINES address type (used for FT_VINES) */
373 static int vines_address_type = -1;
374
375 /* Points to the first element of an array of bits, indexed by
376    a subtree item type; that array element is TRUE if subtrees of
377    an item of that type are to be expanded. */
378 static guint32 *tree_is_expanded;
379
380 /* Number of elements in that array. */
381 int             num_tree_types;
382
383 /* Name hashtables for fast detection of duplicate names */
384 static GHashTable* proto_names        = NULL;
385 static GHashTable* proto_short_names  = NULL;
386 static GHashTable* proto_filter_names = NULL;
387
388 static gint
389 proto_compare_name(gconstpointer p1_arg, gconstpointer p2_arg)
390 {
391         const protocol_t *p1 = (const protocol_t *)p1_arg;
392         const protocol_t *p2 = (const protocol_t *)p2_arg;
393
394         return g_ascii_strcasecmp(p1->short_name, p2->short_name);
395 }
396
397 #ifdef HAVE_PLUGINS
398 /*
399  * List of dissector plugins.
400  */
401 typedef struct {
402         void (*register_protoinfo)(void);       /* routine to call to register protocol information */
403         void (*reg_handoff)(void);              /* routine to call to register dissector handoff */
404 } dissector_plugin;
405
406 static GSList *dissector_plugins = NULL;
407
408 /*
409  * Callback for each plugin found.
410  */
411 static gboolean
412 check_for_dissector_plugin(GModule *handle)
413 {
414         gpointer gp;
415         void (*register_protoinfo)(void);
416         void (*reg_handoff)(void);
417         dissector_plugin *plugin;
418
419         /*
420          * Do we have a register routine?
421          */
422         if (g_module_symbol(handle, "plugin_register", &gp)) {
423 DIAG_OFF(pedantic)
424                 register_protoinfo = (void (*)(void))gp;
425 DIAG_ON(pedantic)
426         }
427         else {
428                 register_protoinfo = NULL;
429         }
430
431         /*
432          * Do we have a reg_handoff routine?
433          */
434         if (g_module_symbol(handle, "plugin_reg_handoff", &gp)) {
435 DIAG_OFF(pedantic)
436                 reg_handoff = (void (*)(void))gp;
437 DIAG_ON(pedantic)
438         }
439         else {
440                 reg_handoff = NULL;
441         }
442
443         /*
444          * If we have neither, we're not a dissector plugin.
445          */
446         if (register_protoinfo == NULL && reg_handoff == NULL)
447                 return FALSE;
448
449         /*
450          * Add this one to the list of dissector plugins.
451          */
452         plugin = (dissector_plugin *)g_malloc(sizeof (dissector_plugin));
453         plugin->register_protoinfo = register_protoinfo;
454         plugin->reg_handoff = reg_handoff;
455         dissector_plugins = g_slist_append(dissector_plugins, plugin);
456         return TRUE;
457 }
458
459 static void
460 register_dissector_plugin(gpointer data, gpointer user_data _U_)
461 {
462         dissector_plugin *plugin = (dissector_plugin *)data;
463
464         if (plugin->register_protoinfo)
465                 (plugin->register_protoinfo)();
466 }
467
468 static void
469 reg_handoff_dissector_plugin(gpointer data, gpointer user_data _U_)
470 {
471         dissector_plugin *plugin = (dissector_plugin *)data;
472
473         if (plugin->reg_handoff)
474                 (plugin->reg_handoff)();
475 }
476
477 /*
478  * Register dissector plugin type.
479  */
480 void
481 register_dissector_plugin_type(void)
482 {
483         add_plugin_type("dissector", check_for_dissector_plugin);
484 }
485 #endif /* HAVE_PLUGINS */
486
487 /* initialize data structures and register protocols and fields */
488 void
489 proto_init(void (register_all_protocols_func)(register_cb cb, gpointer client_data),
490            void (register_all_handoffs_func)(register_cb cb, gpointer client_data),
491            register_cb cb,
492            gpointer client_data)
493 {
494         proto_cleanup();
495
496         proto_names        = g_hash_table_new_full(g_int_hash, g_int_equal, g_free, NULL);
497         proto_short_names  = g_hash_table_new(wrs_str_hash, g_str_equal);
498         proto_filter_names = g_hash_table_new(wrs_str_hash, g_str_equal);
499
500         gpa_hfinfo.len           = 0;
501         gpa_hfinfo.allocated_len = 0;
502         gpa_hfinfo.hfi           = NULL;
503         gpa_name_map             = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, save_same_name_hfinfo);
504         deregistered_fields      = g_ptr_array_new();
505         deregistered_data        = g_ptr_array_new();
506
507         /* Initialize the ftype subsystem */
508         ftypes_initialize();
509
510         /* Initialize the addres type subsystem */
511         address_types_initialize();
512
513         /* Register one special-case FT_TEXT_ONLY field for use when
514            converting wireshark to new-style proto_tree. These fields
515            are merely strings on the GUI tree; they are not filterable */
516         hf_text_only = proto_register_field_init(&hfi_text_only, -1);
517
518         /* Register the pseudo-protocols used for exceptions. */
519         register_show_exception();
520         register_type_length_mismatch();
521         register_number_string_decoding_error();
522
523         /* Have each built-in dissector register its protocols, fields,
524            dissector tables, and dissectors to be called through a
525            handle, and do whatever one-time initialization it needs to
526            do. */
527         register_all_protocols_func(cb, client_data);
528
529         /* Now that the VINES dissector has registered it's address
530            type, grab the value for the field type */
531         vines_address_type = address_type_get_by_name("AT_VINES");
532 #ifdef HAVE_PLUGINS
533         /* Now call the registration routines for all disssector
534            plugins. */
535         if (cb)
536                 (*cb)(RA_PLUGIN_REGISTER, NULL, client_data);
537         g_slist_foreach(dissector_plugins, register_dissector_plugin, NULL);
538 #endif
539
540         /* Now call the "handoff registration" routines of all built-in
541            dissectors; those routines register the dissector in other
542            dissectors' handoff tables, and fetch any dissector handles
543            they need. */
544         register_all_handoffs_func(cb, client_data);
545
546 #ifdef HAVE_PLUGINS
547         /* Now do the same with plugins. */
548         if (cb)
549                 (*cb)(RA_PLUGIN_HANDOFF, NULL, client_data);
550         g_slist_foreach(dissector_plugins, reg_handoff_dissector_plugin, NULL);
551 #endif
552
553         /* sort the protocols by protocol name */
554         protocols = g_list_sort(protocols, proto_compare_name);
555
556         /* We've assigned all the subtree type values; allocate the array
557            for them, and zero it out. */
558         tree_is_expanded = g_new0(guint32, (num_tree_types/32)+1);
559 }
560
561 void
562 proto_cleanup(void)
563 {
564         /* Free the abbrev/ID hash table */
565         if (gpa_name_map) {
566                 g_hash_table_destroy(gpa_name_map);
567                 gpa_name_map = NULL;
568         }
569         g_free(last_field_name);
570         last_field_name = NULL;
571
572         while (protocols) {
573                 protocol_t        *protocol = (protocol_t *)protocols->data;
574                 header_field_info *hfinfo;
575                 PROTO_REGISTRAR_GET_NTH(protocol->proto_id, hfinfo);
576                 DISSECTOR_ASSERT(protocol->proto_id == hfinfo->id);
577
578                 g_slice_free(header_field_info, hfinfo);
579                 g_ptr_array_free(protocol->fields, TRUE);
580                 g_list_free(protocol->heur_list);
581                 protocols = g_list_remove(protocols, protocol);
582                 g_free(protocol);
583         }
584
585         if (proto_names) {
586                 g_hash_table_destroy(proto_names);
587                 proto_names = NULL;
588         }
589
590         if (proto_short_names) {
591                 g_hash_table_destroy(proto_short_names);
592                 proto_short_names = NULL;
593         }
594
595         if (proto_filter_names) {
596                 g_hash_table_destroy(proto_filter_names);
597                 proto_filter_names = NULL;
598         }
599
600         if (gpa_hfinfo.allocated_len) {
601                 gpa_hfinfo.len           = 0;
602                 gpa_hfinfo.allocated_len = 0;
603                 g_free(gpa_hfinfo.hfi);
604                 gpa_hfinfo.hfi           = NULL;
605         }
606
607         if (deregistered_fields) {
608                 g_ptr_array_free(deregistered_fields, FALSE);
609                 deregistered_fields = NULL;
610         }
611
612         if (deregistered_data) {
613                 g_ptr_array_free(deregistered_data, FALSE);
614                 deregistered_data = NULL;
615         }
616
617         g_free(tree_is_expanded);
618         tree_is_expanded = NULL;
619 }
620
621 static gboolean
622 proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
623                               gpointer data)
624 {
625         proto_node *pnode = tree;
626         proto_node *child;
627         proto_node *current;
628
629         if (func(pnode, data))
630                 return TRUE;
631
632         child = pnode->first_child;
633         while (child != NULL) {
634                 /*
635                  * The routine we call might modify the child, e.g. by
636                  * freeing it, so we get the child's successor before
637                  * calling that routine.
638                  */
639                 current = child;
640                 child   = current->next;
641                 if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
642                         return TRUE;
643         }
644
645         return FALSE;
646 }
647
648 gboolean
649 proto_tree_traverse_post_order(proto_tree *tree, proto_tree_traverse_func func,
650                                gpointer data)
651 {
652         proto_node *pnode = tree;
653         proto_node *child;
654         proto_node *current;
655
656         child = pnode->first_child;
657         while (child != NULL) {
658                 /*
659                  * The routine we call might modify the child, e.g. by
660                  * freeing it, so we get the child's successor before
661                  * calling that routine.
662                  */
663                 current = child;
664                 child   = current->next;
665                 if (proto_tree_traverse_post_order((proto_tree *)current, func, data))
666                         return TRUE;
667         }
668         if (func(pnode, data))
669                 return TRUE;
670
671         return FALSE;
672 }
673
674 void
675 proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
676                             gpointer data)
677 {
678         proto_node *node = tree;
679         proto_node *current;
680
681         if (!node)
682                 return;
683
684         node = node->first_child;
685         while (node != NULL) {
686                 current = node;
687                 node    = current->next;
688                 func((proto_tree *)current, data);
689         }
690 }
691
692 static void
693 free_GPtrArray_value(gpointer key, gpointer value, gpointer user_data _U_)
694 {
695         GPtrArray         *ptrs = (GPtrArray *)value;
696         gint               hfid = GPOINTER_TO_UINT(key);
697         header_field_info *hfinfo;
698
699         PROTO_REGISTRAR_GET_NTH(hfid, hfinfo);
700         if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
701                 /* when a field is referenced by a filter this also
702                    affects the refcount for the parent protocol so we need
703                    to adjust the refcount for the parent as well
704                 */
705                 if (hfinfo->parent != -1) {
706                         header_field_info *parent_hfinfo;
707                         PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
708                         parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
709                 }
710                 hfinfo->ref_type = HF_REF_TYPE_NONE;
711         }
712
713         g_ptr_array_free(ptrs, TRUE);
714 }
715
716 static void
717 proto_tree_free_node(proto_node *node, gpointer data _U_)
718 {
719         field_info *finfo  = PNODE_FINFO(node);
720
721         proto_tree_children_foreach(node, proto_tree_free_node, NULL);
722
723         FVALUE_CLEANUP(&finfo->value);
724 }
725
726 void
727 proto_tree_reset(proto_tree *tree)
728 {
729         tree_data_t *tree_data = PTREE_DATA(tree);
730
731         proto_tree_children_foreach(tree, proto_tree_free_node, NULL);
732
733         /* free tree data */
734         if (tree_data->interesting_hfids) {
735                 /* Free all the GPtrArray's in the interesting_hfids hash. */
736                 g_hash_table_foreach(tree_data->interesting_hfids,
737                         free_GPtrArray_value, NULL);
738
739                 /* And then remove all values. */
740                 g_hash_table_remove_all(tree_data->interesting_hfids);
741         }
742
743         /* Reset track of the number of children */
744         tree_data->count = 0;
745
746         PROTO_NODE_INIT(tree);
747 }
748
749 /* frees the resources that the dissection a proto_tree uses */
750 void
751 proto_tree_free(proto_tree *tree)
752 {
753         tree_data_t *tree_data = PTREE_DATA(tree);
754
755         proto_tree_children_foreach(tree, proto_tree_free_node, NULL);
756
757         /* free tree data */
758         if (tree_data->interesting_hfids) {
759                 /* Free all the GPtrArray's in the interesting_hfids hash. */
760                 g_hash_table_foreach(tree_data->interesting_hfids,
761                         free_GPtrArray_value, NULL);
762
763                 /* And then destroy the hash. */
764                 g_hash_table_destroy(tree_data->interesting_hfids);
765         }
766
767         g_slice_free(tree_data_t, tree_data);
768
769         g_slice_free(proto_tree, tree);
770 }
771
772 /* Is the parsing being done for a visible proto_tree or an invisible one?
773  * By setting this correctly, the proto_tree creation is sped up by not
774  * having to call g_vsnprintf and copy strings around.
775  */
776 gboolean
777 proto_tree_set_visible(proto_tree *tree, gboolean visible)
778 {
779         gboolean old_visible = PTREE_DATA(tree)->visible;
780
781         PTREE_DATA(tree)->visible = visible;
782
783         return old_visible;
784 }
785
786 void
787 proto_tree_set_fake_protocols(proto_tree *tree, gboolean fake_protocols)
788 {
789         PTREE_DATA(tree)->fake_protocols = fake_protocols;
790 }
791
792 /* Assume dissector set only its protocol fields.
793    This function is called by dissectors and allows the speeding up of filtering
794    in wireshark; if this function returns FALSE it is safe to reset tree to NULL
795    and thus skip calling most of the expensive proto_tree_add_...()
796    functions.
797    If the tree is visible we implicitly assume the field is referenced.
798 */
799 gboolean
800 proto_field_is_referenced(proto_tree *tree, int proto_id)
801 {
802         register header_field_info *hfinfo;
803
804
805         if (!tree)
806                 return FALSE;
807
808         if (PTREE_DATA(tree)->visible)
809                 return TRUE;
810
811         PROTO_REGISTRAR_GET_NTH(proto_id, hfinfo);
812         if (hfinfo->ref_type != HF_REF_TYPE_NONE)
813                 return TRUE;
814
815         if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)->fake_protocols)
816                 return TRUE;
817
818         return FALSE;
819 }
820
821
822 /* Finds a record in the hfinfo array by id. */
823 header_field_info *
824 proto_registrar_get_nth(guint hfindex)
825 {
826         register header_field_info *hfinfo;
827
828         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
829         return hfinfo;
830 }
831
832
833 /*      Prefix initialization
834  *        this allows for a dissector to register a display filter name prefix
835  *        so that it can delay the initialization of the hf array as long as
836  *        possible.
837  */
838
839 /* compute a hash for the part before the dot of a display filter */
840 static guint
841 prefix_hash (gconstpointer key) {
842         /* end the string at the dot and compute its hash */
843         gchar* copy = g_strdup((const gchar *)key);
844         gchar* c    = copy;
845         guint tmp;
846
847         for (; *c; c++) {
848                 if (*c == '.') {
849                         *c = 0;
850                         break;
851                 }
852         }
853
854         tmp = g_str_hash(copy);
855         g_free(copy);
856         return tmp;
857 }
858
859 /* are both strings equal up to the end or the dot? */
860 static gboolean
861 prefix_equal (gconstpointer ap, gconstpointer bp) {
862         const gchar* a = (const gchar *)ap;
863         const gchar* b = (const gchar *)bp;
864
865         do {
866                 gchar ac = *a++;
867                 gchar bc = *b++;
868
869                 if ( (ac == '.' || ac == '\0') &&   (bc == '.' || bc == '\0') ) return TRUE;
870
871                 if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE;
872                 if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE;
873
874                 if (ac != bc) return FALSE;
875         } while (1);
876
877         return FALSE;
878 }
879
880
881 /* indexed by prefix, contains initializers */
882 static GHashTable* prefixes = NULL;
883
884
885 /* Register a new prefix for "delayed" initialization of field arrays */
886 void
887 proto_register_prefix(const char *prefix, prefix_initializer_t pi ) {
888         if (! prefixes ) {
889                 prefixes = g_hash_table_new(prefix_hash, prefix_equal);
890         }
891
892         g_hash_table_insert(prefixes, (gpointer)prefix, (gpointer)pi);
893 }
894
895 /* helper to call all prefix initializers */
896 static gboolean
897 initialize_prefix(gpointer k, gpointer v, gpointer u _U_) {
898         ((prefix_initializer_t)v)((const char *)k);
899         return TRUE;
900 }
901
902 /** Initialize every remaining uninitialized prefix. */
903 void
904 proto_initialize_all_prefixes(void) {
905         g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL);
906 }
907
908 /* Finds a record in the hfinfo array by name.
909  * If it fails to find it in the already registered fields,
910  * it tries to find and call an initializer in the prefixes
911  * table and if so it looks again.
912  */
913
914 header_field_info *
915 proto_registrar_get_byname(const char *field_name)
916 {
917         header_field_info    *hfinfo;
918         prefix_initializer_t  pi;
919
920         if (!field_name)
921                 return NULL;
922
923         if (g_strcmp0(field_name, last_field_name) == 0) {
924                 return last_hfinfo;
925         }
926
927         hfinfo = (header_field_info *)g_hash_table_lookup(gpa_name_map, field_name);
928
929         if (hfinfo) {
930                 g_free(last_field_name);
931                 last_field_name = g_strdup(field_name);
932                 last_hfinfo = hfinfo;
933                 return hfinfo;
934         }
935
936         if (!prefixes)
937                 return NULL;
938
939         if ((pi = (prefix_initializer_t)g_hash_table_lookup(prefixes, field_name) ) != NULL) {
940                 pi(field_name);
941                 g_hash_table_remove(prefixes, field_name);
942         } else {
943                 return NULL;
944         }
945
946         hfinfo = (header_field_info *)g_hash_table_lookup(gpa_name_map, field_name);
947
948         if (hfinfo) {
949                 g_free(last_field_name);
950                 last_field_name = g_strdup(field_name);
951                 last_hfinfo = hfinfo;
952         }
953         return hfinfo;
954 }
955
956 int
957 proto_registrar_get_id_byname(const char *field_name)
958 {
959         header_field_info *hfinfo;
960
961         hfinfo = proto_registrar_get_byname(field_name);
962
963         if (!hfinfo)
964                 return -1;
965
966         return hfinfo->id;
967 }
968
969
970 static void
971 ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
972 {
973         subtree_lvl *pushed_tree;
974
975         DISSECTOR_ASSERT(ptvc->pushed_tree_max <= SUBTREE_MAX_LEVELS-SUBTREE_ONCE_ALLOCATION_NUMBER);
976         ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER;
977
978         pushed_tree = (subtree_lvl *)wmem_alloc(wmem_packet_scope(), sizeof(subtree_lvl) * ptvc->pushed_tree_max);
979         DISSECTOR_ASSERT(pushed_tree != NULL);
980         if (ptvc->pushed_tree)
981                 memcpy(pushed_tree, ptvc->pushed_tree, ptvc->pushed_tree_max - SUBTREE_ONCE_ALLOCATION_NUMBER);
982         ptvc->pushed_tree = pushed_tree;
983 }
984
985 static void
986 ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
987 {
988         ptvc->pushed_tree       = NULL;
989         ptvc->pushed_tree_max   = 0;
990         DISSECTOR_ASSERT(ptvc->pushed_tree_index == 0);
991         ptvc->pushed_tree_index = 0;
992 }
993
994 /* Allocates an initializes a ptvcursor_t with 3 variables:
995  *      proto_tree, tvbuff, and offset. */
996 ptvcursor_t *
997 ptvcursor_new(proto_tree *tree, tvbuff_t *tvb, gint offset)
998 {
999         ptvcursor_t *ptvc;
1000
1001         ptvc                    = (ptvcursor_t *)wmem_alloc(wmem_packet_scope(), sizeof(ptvcursor_t));
1002         ptvc->tree              = tree;
1003         ptvc->tvb               = tvb;
1004         ptvc->offset            = offset;
1005         ptvc->pushed_tree       = NULL;
1006         ptvc->pushed_tree_max   = 0;
1007         ptvc->pushed_tree_index = 0;
1008         return ptvc;
1009 }
1010
1011
1012 /* Frees memory for ptvcursor_t, but nothing deeper than that. */
1013 void
1014 ptvcursor_free(ptvcursor_t *ptvc)
1015 {
1016         ptvcursor_free_subtree_levels(ptvc);
1017         /*g_free(ptvc);*/
1018 }
1019
1020 /* Returns tvbuff. */
1021 tvbuff_t *
1022 ptvcursor_tvbuff(ptvcursor_t *ptvc)
1023 {
1024         return ptvc->tvb;
1025 }
1026
1027 /* Returns current offset. */
1028 gint
1029 ptvcursor_current_offset(ptvcursor_t *ptvc)
1030 {
1031         return ptvc->offset;
1032 }
1033
1034 proto_tree *
1035 ptvcursor_tree(ptvcursor_t *ptvc)
1036 {
1037         if (!ptvc)
1038                 return NULL;
1039
1040         return ptvc->tree;
1041 }
1042
1043 void
1044 ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
1045 {
1046         ptvc->tree = tree;
1047 }
1048
1049 /* creates a subtree, sets it as the working tree and pushes the old working tree */
1050 proto_tree *
1051 ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree)
1052 {
1053         subtree_lvl *subtree;
1054         if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
1055                 ptvcursor_new_subtree_levels(ptvc);
1056
1057         subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1058         subtree->tree = ptvc->tree;
1059         subtree->it= NULL;
1060         ptvc->pushed_tree_index++;
1061         return ptvcursor_set_subtree(ptvc, it, ett_subtree);
1062 }
1063
1064 /* pops a subtree */
1065 void
1066 ptvcursor_pop_subtree(ptvcursor_t *ptvc)
1067 {
1068         subtree_lvl *subtree;
1069
1070         if (ptvc->pushed_tree_index <= 0)
1071                 return;
1072
1073         ptvc->pushed_tree_index--;
1074         subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1075         if (subtree->it != NULL)
1076                 proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
1077
1078         ptvc->tree = subtree->tree;
1079 }
1080
1081 /* saves the current tvb offset and the item in the current subtree level */
1082 static void
1083 ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
1084 {
1085         subtree_lvl *subtree;
1086
1087         DISSECTOR_ASSERT(ptvc->pushed_tree_index > 0);
1088
1089         subtree                = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
1090         subtree->it            = it;
1091         subtree->cursor_offset = ptvcursor_current_offset(ptvc);
1092 }
1093
1094 /* Creates a subtree and adds it to the cursor as the working tree but does not
1095  * save the old working tree */
1096 proto_tree *
1097 ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree)
1098 {
1099         ptvc->tree = proto_item_add_subtree(it, ett_subtree);
1100         return ptvc->tree;
1101 }
1102
1103 static proto_tree *
1104 ptvcursor_add_subtree_item(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree, gint length)
1105 {
1106         ptvcursor_push_subtree(ptvc, it, ett_subtree);
1107         if (length == SUBTREE_UNDEFINED_LENGTH)
1108                 ptvcursor_subtree_set_item(ptvc, it);
1109         return ptvcursor_tree(ptvc);
1110 }
1111
1112 /* Add an item to the tree and create a subtree
1113  * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1114  * In this case, when the subtree will be closed, the parent item length will
1115  * be equal to the advancement of the cursor since the creation of the subtree.
1116  */
1117 proto_tree *
1118 ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, gint length,
1119                            const guint encoding, gint ett_subtree)
1120 {
1121         proto_item *it;
1122
1123         it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
1124         return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
1125 }
1126
1127 static proto_item *
1128 proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, gint start, gint length);
1129
1130 /* Add a text node to the tree and create a subtree
1131  * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1132  * In this case, when the subtree will be closed, the item length will be equal
1133  * to the advancement of the cursor since the creation of the subtree.
1134  */
1135 proto_tree *
1136 ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, gint length,
1137                                 gint ett_subtree, const char *format, ...)
1138 {
1139         proto_item        *pi;
1140         va_list            ap;
1141         header_field_info *hfinfo;
1142         proto_tree        *tree;
1143
1144         tree = ptvcursor_tree(ptvc);
1145
1146         CHECK_FOR_NULL_TREE(tree);
1147
1148         TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1149
1150         pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
1151                                       ptvcursor_current_offset(ptvc), length);
1152
1153         TRY_TO_FAKE_THIS_REPR(pi);
1154
1155         va_start(ap, format);
1156         proto_tree_set_representation(pi, format, ap);
1157         va_end(ap);
1158
1159         return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
1160 }
1161
1162 /* Add a text-only node, leaving it to our caller to fill the text in */
1163 static proto_item *
1164 proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, gint start, gint length)
1165 {
1166         proto_item *pi;
1167
1168         if (tree == NULL)
1169                 return NULL;
1170
1171         pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
1172
1173         return pi;
1174 }
1175
1176 /* (INTERNAL USE ONLY) Add a text-only node to the proto_tree */
1177 proto_item *
1178 proto_tree_add_text_internal(proto_tree *tree, tvbuff_t *tvb, gint start, gint length,
1179                     const char *format, ...)
1180 {
1181         proto_item        *pi;
1182         va_list            ap;
1183         header_field_info *hfinfo;
1184
1185         CHECK_FOR_NULL_TREE(tree);
1186
1187         TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1188
1189         pi = proto_tree_add_text_node(tree, tvb, start, length);
1190
1191         TRY_TO_FAKE_THIS_REPR(pi);
1192
1193         va_start(ap, format);
1194         proto_tree_set_representation(pi, format, ap);
1195         va_end(ap);
1196
1197         return pi;
1198 }
1199
1200 /* (INTERNAL USE ONLY) Add a text-only node to the proto_tree (va_list version) */
1201 proto_item *
1202 proto_tree_add_text_valist_internal(proto_tree *tree, tvbuff_t *tvb, gint start,
1203                            gint length, const char *format, va_list ap)
1204 {
1205         proto_item        *pi;
1206         header_field_info *hfinfo;
1207
1208         CHECK_FOR_NULL_TREE(tree);
1209
1210         TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1211
1212         pi = proto_tree_add_text_node(tree, tvb, start, length);
1213
1214         TRY_TO_FAKE_THIS_REPR(pi);
1215
1216         proto_tree_set_representation(pi, format, ap);
1217
1218         return pi;
1219 }
1220
1221 /* Add a text-only node that creates a subtree underneath.
1222  */
1223 proto_tree *
1224 proto_tree_add_subtree(proto_tree *tree, tvbuff_t *tvb, gint start, gint length, gint idx, proto_item **tree_item, const char *text)
1225 {
1226         return proto_tree_add_subtree_format(tree, tvb, start, length, idx, tree_item, "%s", text);
1227 }
1228
1229 /* Add a text-only node that creates a subtree underneath.
1230  */
1231 proto_tree *
1232 proto_tree_add_subtree_format(proto_tree *tree, tvbuff_t *tvb, gint start, gint length, gint idx, proto_item **tree_item, const char *format, ...)
1233 {
1234         proto_tree *pt;
1235         proto_item *pi;
1236         va_list     ap;
1237
1238         va_start(ap, format);
1239         pi = proto_tree_add_text_valist_internal(tree, tvb, start, length, format, ap);
1240         va_end(ap);
1241
1242         if (tree_item != NULL)
1243                 *tree_item = pi;
1244
1245         pt = proto_item_add_subtree(pi, idx);
1246
1247         return pt;
1248 }
1249
1250 /* Add a text-only node for debugging purposes. The caller doesn't need
1251  * to worry about tvbuff, start, or length. Debug message gets sent to
1252  * STDOUT, too */
1253 proto_item *
1254 proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
1255 {
1256         proto_item *pi;
1257         va_list     ap;
1258
1259         pi = proto_tree_add_text_node(tree, NULL, 0, 0);
1260
1261         if (pi) {
1262                 va_start(ap, format);
1263                 proto_tree_set_representation(pi, format, ap);
1264                 va_end(ap);
1265         }
1266         va_start(ap, format);
1267         vprintf(format, ap);
1268         va_end(ap);
1269         printf("\n");
1270
1271         return pi;
1272 }
1273
1274 proto_item *
1275 proto_tree_add_format_text(proto_tree *tree, tvbuff_t *tvb, gint start, gint length)
1276 {
1277         proto_item        *pi;
1278         header_field_info *hfinfo;
1279
1280         CHECK_FOR_NULL_TREE(tree);
1281
1282         TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1283
1284         pi = proto_tree_add_text_node(tree, tvb, start, length);
1285
1286         TRY_TO_FAKE_THIS_REPR(pi);
1287
1288         proto_item_set_text(pi, "%s", tvb_format_text(tvb, start, length));
1289
1290         return pi;
1291 }
1292
1293 proto_item *
1294 proto_tree_add_format_wsp_text(proto_tree *tree, tvbuff_t *tvb, gint start, gint length)
1295 {
1296         proto_item        *pi;
1297         header_field_info *hfinfo;
1298
1299         CHECK_FOR_NULL_TREE(tree);
1300
1301         TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1302
1303         pi = proto_tree_add_text_node(tree, tvb, start, length);
1304
1305         TRY_TO_FAKE_THIS_REPR(pi);
1306
1307         proto_item_set_text(pi, "%s", tvb_format_text_wsp(tvb, start, length));
1308
1309         return pi;
1310 }
1311
1312 void proto_report_dissector_bug(const char *message)
1313 {
1314         if (getenv("WIRESHARK_ABORT_ON_DISSECTOR_BUG") != NULL)
1315                 abort();
1316         else
1317                 THROW_MESSAGE(DissectorError, message);
1318 }
1319
1320 /* We could probably get away with changing is_error to a minimum length value. */
1321 static void
1322 report_type_length_mismatch(proto_tree *tree, const gchar *descr, int length, gboolean is_error) {
1323
1324         if (is_error) {
1325                 expert_add_info_format(NULL, tree, &ei_type_length_mismatch_error, "Trying to fetch %s with length %d", descr, length);
1326         } else {
1327                 expert_add_info_format(NULL, tree, &ei_type_length_mismatch_warn, "Trying to fetch %s with length %d", descr, length);
1328         }
1329
1330         if (is_error) {
1331                 THROW(ReportedBoundsError);
1332         }
1333 }
1334
1335 static guint32
1336 get_uint_value(proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, const guint encoding)
1337 {
1338         guint32 value;
1339         gboolean length_error;
1340
1341         switch (length) {
1342
1343         case 1:
1344                 value = tvb_get_guint8(tvb, offset);
1345                 break;
1346
1347         case 2:
1348                 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohs(tvb, offset)
1349                                                        : tvb_get_ntohs(tvb, offset);
1350                 break;
1351
1352         case 3:
1353                 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh24(tvb, offset)
1354                                                        : tvb_get_ntoh24(tvb, offset);
1355                 break;
1356
1357         case 4:
1358                 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohl(tvb, offset)
1359                                                        : tvb_get_ntohl(tvb, offset);
1360                 break;
1361
1362         default:
1363                 if (length < 1) {
1364                         length_error = TRUE;
1365                         value = 0;
1366                 } else {
1367                         length_error = FALSE;
1368                         value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohl(tvb, offset)
1369                                                                : tvb_get_ntohl(tvb, offset);
1370                 }
1371                 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1372                 break;
1373         }
1374         return value;
1375 }
1376
1377 static inline guint64
1378 get_uint64_value(proto_tree *tree, tvbuff_t *tvb, gint offset, guint length, const guint encoding)
1379 {
1380         guint64 value;
1381         gboolean length_error;
1382
1383         switch (length) {
1384
1385         case 1:
1386                 value = tvb_get_guint8(tvb, offset);
1387                 break;
1388
1389         case 2:
1390                 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohs(tvb, offset)
1391                                                        : tvb_get_ntohs(tvb, offset);
1392                 break;
1393
1394         case 3:
1395                 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh24(tvb, offset)
1396                                                        : tvb_get_ntoh24(tvb, offset);
1397                 break;
1398
1399         case 4:
1400                 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohl(tvb, offset)
1401                                                        : tvb_get_ntohl(tvb, offset);
1402                 break;
1403
1404         case 5:
1405                 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh40(tvb, offset)
1406                                                        : tvb_get_ntoh40(tvb, offset);
1407                 break;
1408
1409         case 6:
1410                 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh48(tvb, offset)
1411                                                        : tvb_get_ntoh48(tvb, offset);
1412                 break;
1413
1414         case 7:
1415                 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh56(tvb, offset)
1416                                                        : tvb_get_ntoh56(tvb, offset);
1417                 break;
1418
1419         case 8:
1420                 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh64(tvb, offset)
1421                                                        : tvb_get_ntoh64(tvb, offset);
1422                 break;
1423
1424         default:
1425                 if (length < 1) {
1426                         length_error = TRUE;
1427                         value = 0;
1428                 } else {
1429                         length_error = FALSE;
1430                         value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh64(tvb, offset)
1431                                                                : tvb_get_ntoh64(tvb, offset);
1432                 }
1433                 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1434                 break;
1435         }
1436         return value;
1437 }
1438
1439 static gint32
1440 get_int_value(proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, const guint encoding)
1441 {
1442         gint32 value;
1443         gboolean length_error;
1444
1445         switch (length) {
1446
1447         case 1:
1448                 value = (gint8)tvb_get_guint8(tvb, offset);
1449                 break;
1450
1451         case 2:
1452                 value = (gint16) (encoding ? tvb_get_letohs(tvb, offset)
1453                                            : tvb_get_ntohs(tvb, offset));
1454                 break;
1455
1456         case 3:
1457                 value = encoding ? tvb_get_letoh24(tvb, offset)
1458                                  : tvb_get_ntoh24(tvb, offset);
1459                 if (value & 0x00800000) {
1460                         /* Sign bit is set; sign-extend it. */
1461                         value |= 0xFF000000;
1462                 }
1463                 break;
1464
1465         case 4:
1466                 value = encoding ? tvb_get_letohl(tvb, offset)
1467                                  : tvb_get_ntohl(tvb, offset);
1468                 break;
1469
1470         default:
1471                 if (length < 1) {
1472                         length_error = TRUE;
1473                         value = 0;
1474                 } else {
1475                         length_error = FALSE;
1476                         value = encoding ? tvb_get_letohl(tvb, offset)
1477                                          : tvb_get_ntohl(tvb, offset);
1478                 }
1479                 report_type_length_mismatch(tree, "a signed integer", length, length_error);
1480                 break;
1481         }
1482         return value;
1483 }
1484
1485 /* Note: this returns an unsigned int64, but with the appropriate bit(s) set to
1486  * be cast-able as a gint64. This is weird, but what the code has always done.
1487  */
1488 static inline guint64
1489 get_int64_value(proto_tree *tree, tvbuff_t *tvb, gint start, guint length, const guint encoding)
1490 {
1491         guint64 value = get_uint64_value(tree, tvb, start, length, encoding);
1492
1493         switch(length)
1494         {
1495                 case 7:
1496                         value = ws_sign_ext64(value, 56);
1497                         break;
1498                 case 6:
1499                         value = ws_sign_ext64(value, 48);
1500                         break;
1501                 case 5:
1502                         value = ws_sign_ext64(value, 40);
1503                         break;
1504                 case 4:
1505                         value = ws_sign_ext64(value, 32);
1506                         break;
1507                 case 3:
1508                         value = ws_sign_ext64(value, 24);
1509                         break;
1510                 case 2:
1511                         value = ws_sign_ext64(value, 16);
1512                         break;
1513                 case 1:
1514                         value = ws_sign_ext64(value, 8);
1515                         break;
1516         }
1517
1518         return value;
1519 }
1520
1521 /* For FT_STRING */
1522 static inline const guint8 *
1523 get_string_value(wmem_allocator_t *scope, tvbuff_t *tvb, gint start,
1524     gint length, gint *ret_length, const guint encoding)
1525 {
1526         if (length == -1) {
1527                 length = tvb_ensure_captured_length_remaining(tvb, start);
1528         }
1529         *ret_length = length;
1530         return tvb_get_string_enc(scope, tvb, start, length, encoding);
1531 }
1532
1533 /* For FT_STRINGZ */
1534 static inline const guint8 *
1535 get_stringz_value(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb,
1536     gint start, gint length, gint *ret_length, const guint encoding)
1537 {
1538         const guint8 *value;
1539
1540         if (length < -1) {
1541                 report_type_length_mismatch(tree, "a string", length, TRUE);
1542         }
1543         if (length == -1) {
1544                 /* This can throw an exception */
1545                 value = tvb_get_stringz_enc(scope, tvb, start, &length, encoding);
1546         } else if (length == 0) {
1547                 value = "[Empty]";
1548         } else {
1549                 /* In this case, length signifies the length of the string.
1550                  *
1551                  * This could either be a null-padded string, which doesn't
1552                  * necessarily have a '\0' at the end, or a null-terminated
1553                  * string, with a trailing '\0'.  (Yes, there are cases
1554                  * where you have a string that's both counted and null-
1555                  * terminated.)
1556                  *
1557                  * In the first case, we must allocate a buffer of length
1558                  * "length+1", to make room for a trailing '\0'.
1559                  *
1560                  * In the second case, we don't assume that there is a
1561                  * trailing '\0' there, as the packet might be malformed.
1562                  * (XXX - should we throw an exception if there's no
1563                  * trailing '\0'?)  Therefore, we allocate a buffer of
1564                  * length "length+1", and put in a trailing '\0', just to
1565                  * be safe.
1566                  *
1567                  * (XXX - this would change if we made string values counted
1568                  * rather than null-terminated.)
1569                  */
1570                 value = tvb_get_string_enc(scope, tvb, start, length, encoding);
1571         }
1572         *ret_length = length;
1573         return value;
1574 }
1575
1576 /* For FT_UINT_STRING */
1577 static inline const guint8 *
1578 get_uint_string_value(wmem_allocator_t *scope, proto_tree *tree,
1579     tvbuff_t *tvb, gint start, gint length, gint *ret_length,
1580     const guint encoding)
1581 {
1582         guint32 n;
1583         const guint8 *value;
1584
1585         /* I believe it's ok if this is called with a NULL tree */
1586         n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK);
1587         value = tvb_get_string_enc(scope, tvb, start + length, n, encoding);
1588         length += n;
1589         *ret_length = length;
1590         return value;
1591 }
1592
1593 /* For FT_STRINGZPAD */
1594 static inline const guint8 *
1595 get_stringzpad_value(wmem_allocator_t *scope, tvbuff_t *tvb, gint start,
1596     gint length, gint *ret_length, const guint encoding)
1597 {
1598         /*
1599          * XXX - currently, string values are null-
1600          * terminated, so a "zero-padded" string
1601          * isn't special.  If we represent string
1602          * values as something that includes a counted
1603          * array of bytes, we'll need to strip
1604          * trailing NULs.
1605          */
1606         if (length == -1) {
1607                 length = tvb_ensure_captured_length_remaining(tvb, start);
1608         }
1609         *ret_length = length;
1610         return tvb_get_string_enc(scope, tvb, start, length, encoding);
1611 }
1612
1613 /* this can be called when there is no tree, so don't add that as a param */
1614 static void
1615 get_time_value(tvbuff_t *tvb, const gint start, const gint length, const guint encoding,
1616                nstime_t *time_stamp, const gboolean is_relative)
1617 {
1618         guint32     tmpsecs;
1619         guint64     todsecs;
1620
1621         /* relative timestamps don't do TOD/NTP */
1622         if (is_relative &&
1623                 (encoding != (ENC_TIME_TIMESPEC|ENC_BIG_ENDIAN)) &&
1624                 (encoding != (ENC_TIME_TIMESPEC|ENC_LITTLE_ENDIAN)) )
1625         {
1626                 /* XXX: I think this should call REPORT_DISSECTOR_BUG(), but
1627                    the existing code didn't do that, so I'm not either */
1628                 return;
1629         }
1630
1631         switch (encoding) {
1632
1633                 case ENC_TIME_TIMESPEC|ENC_BIG_ENDIAN:
1634                         /*
1635                          * 4-byte UNIX epoch, possibly followed by
1636                          * 4-byte fractional time in nanoseconds,
1637                          * both big-endian.
1638                          */
1639                         time_stamp->secs  = (time_t)tvb_get_ntohl(tvb, start);
1640                         if (length == 8)
1641                                 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4);
1642                         else
1643                                 time_stamp->nsecs = 0;
1644                         break;
1645
1646                 case ENC_TIME_TIMESPEC|ENC_LITTLE_ENDIAN:
1647                         /*
1648                          * 4-byte UNIX epoch, possibly followed by
1649                          * 4-byte fractional time in nanoseconds,
1650                          * both little-endian.
1651                          */
1652                         time_stamp->secs  = (time_t)tvb_get_letohl(tvb, start);
1653                         if (length == 8)
1654                                 time_stamp->nsecs = tvb_get_letohl(tvb, start+4);
1655                         else
1656                                 time_stamp->nsecs = 0;
1657                         break;
1658
1659                 case ENC_TIME_TOD|ENC_BIG_ENDIAN:
1660                         /*
1661                          * TOD time stamp, big-endian.
1662                          */
1663 /* XXX - where should this go? */
1664 #define TOD_BASETIME G_GUINT64_CONSTANT(2208988800)
1665
1666                         todsecs  = tvb_get_ntoh64(tvb, start) >> 12;
1667                         time_stamp->secs = (time_t)((todsecs  / 1000000) - TOD_BASETIME);
1668                         time_stamp->nsecs = (int)((todsecs  % 1000000) * 1000);
1669                         break;
1670
1671                 case ENC_TIME_TOD|ENC_LITTLE_ENDIAN:
1672                         /*
1673                          * TOD time stamp, big-endian.
1674                          */
1675                         todsecs  = tvb_get_letoh64(tvb, start) >> 12 ;
1676                         time_stamp->secs = (time_t)((todsecs  / 1000000) - TOD_BASETIME);
1677                         time_stamp->nsecs = (int)((todsecs  % 1000000) * 1000);
1678                         break;
1679
1680                 case ENC_TIME_NTP|ENC_BIG_ENDIAN:
1681                         /*
1682                          * NTP time stamp, big-endian.
1683                          */
1684
1685 /* XXX - where should this go? */
1686 #define NTP_BASETIME G_GUINT64_CONSTANT(2208988800)
1687
1688                         /* We need a temporary variable here so the unsigned math
1689                          * works correctly (for years > 2036 according to RFC 2030
1690                          * chapter 3).
1691                          */
1692                         tmpsecs  = tvb_get_ntohl(tvb, start);
1693                         if (tmpsecs)
1694                                 time_stamp->secs = (time_t)(tmpsecs - (guint32)NTP_BASETIME);
1695                         else
1696                                 time_stamp->secs = tmpsecs; /* 0 */
1697
1698                         if (length == 8) {
1699                                 /*
1700                                  * We're using nanoseconds here (and we will
1701                                  * display nanoseconds), but NTP's timestamps
1702                                  * have a precision in microseconds or greater.
1703                                  * Round to 1 microsecond.
1704                                  */
1705                                 time_stamp->nsecs = (int)(1000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
1706                                 time_stamp->nsecs *= 1000;
1707                         } else {
1708                                 time_stamp->nsecs = 0;
1709                         }
1710                         break;
1711
1712                 case ENC_TIME_NTP|ENC_LITTLE_ENDIAN:
1713                         /*
1714                          * NTP time stamp, big-endian.
1715                          */
1716                         tmpsecs  = tvb_get_letohl(tvb, start);
1717                         if (tmpsecs)
1718                                 time_stamp->secs = (time_t)(tmpsecs - (guint32)NTP_BASETIME);
1719                         else
1720                                 time_stamp->secs = tmpsecs; /* 0 */
1721
1722                         if (length == 8) {
1723                                 /*
1724                                  * We're using nanoseconds here (and we will
1725                                  * display nanoseconds), but NTP's timestamps
1726                                  * have a precision in microseconds or greater.
1727                                  * Round to 1 microsecond.
1728                                  */
1729                                 time_stamp->nsecs = (int)(1000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
1730                                 time_stamp->nsecs *= 1000;
1731                         } else {
1732                                 time_stamp->nsecs = 0;
1733                         }
1734                         break;
1735                 case ENC_TIME_NTP_BASE_ZERO|ENC_BIG_ENDIAN:
1736                         /*
1737                          * DDS NTP time stamp, big-endian.
1738                          */
1739
1740 #define NTP_BASETIME_ZERO G_GUINT64_CONSTANT(0)
1741
1742                         tmpsecs  = tvb_get_ntohl(tvb, start);
1743                         if (tmpsecs)
1744                                 time_stamp->secs = (time_t)(tmpsecs - (guint32)NTP_BASETIME_ZERO);
1745                         else
1746                                 time_stamp->secs = tmpsecs; /* 0 */
1747
1748                         if (length == 8) {
1749                                 /*
1750                                  * We're using nanoseconds here (and we will
1751                                  * display nanoseconds), but NTP's timestamps
1752                                  * have a precision in microseconds or greater.
1753                                  * Round to 1 microsecond.
1754                                  */
1755                                 time_stamp->nsecs = (int)(1000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
1756                                 time_stamp->nsecs *= 1000;
1757                         } else {
1758                                 time_stamp->nsecs = 0;
1759                         }
1760                         break;
1761
1762                 case ENC_TIME_NTP_BASE_ZERO|ENC_LITTLE_ENDIAN:
1763                         /*
1764                          * NTP time stamp, big-endian.
1765                          */
1766                         tmpsecs  = tvb_get_letohl(tvb, start);
1767                         if (tmpsecs)
1768                                 time_stamp->secs = (time_t)(tmpsecs - (guint32)NTP_BASETIME_ZERO);
1769                         else
1770                                 time_stamp->secs = tmpsecs; /* 0 */
1771                                                 time_stamp->secs  = (time_t)tvb_get_letohl(tvb, start);
1772                         if (length == 8) {
1773                                 /*
1774                                  * We're using nanoseconds here (and we will
1775                                  * display nanoseconds), but NTP's timestamps
1776                                  * have a precision in microseconds or greater.
1777                                  * Round to 1 microsecond.
1778                                  */
1779                                 time_stamp->nsecs = (int)(1000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
1780                                 time_stamp->nsecs *= 1000;
1781                         } else {
1782                                 time_stamp->nsecs = 0;
1783                         }
1784                         break;
1785
1786                 default:
1787                         DISSECTOR_ASSERT_NOT_REACHED();
1788                         break;
1789         }
1790 }
1791
1792 static void
1793 tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
1794 {
1795         const header_field_info *hfinfo = fi->hfinfo;
1796
1797         if (hfinfo->ref_type == HF_REF_TYPE_DIRECT) {
1798                 GPtrArray *ptrs = NULL;
1799
1800                 if (tree_data->interesting_hfids == NULL) {
1801                         /* Initialize the hash because we now know that it is needed */
1802                         tree_data->interesting_hfids =
1803                                 g_hash_table_new(g_direct_hash, NULL /* g_direct_equal */);
1804                 } else if (g_hash_table_size(tree_data->interesting_hfids)) {
1805                         ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
1806                                            GINT_TO_POINTER(hfinfo->id));
1807                 }
1808
1809                 if (!ptrs) {
1810                         /* First element triggers the creation of pointer array */
1811                         ptrs = g_ptr_array_new();
1812                         g_hash_table_insert(tree_data->interesting_hfids,
1813                                             GINT_TO_POINTER(hfinfo->id), ptrs);
1814                 }
1815
1816                 g_ptr_array_add(ptrs, fi);
1817         }
1818 }
1819
1820 /* Add an item to a proto_tree, using the text label registered to that item;
1821    the item is extracted from the tvbuff handed to it. */
1822 static proto_item *
1823 proto_tree_new_item(field_info *new_fi, proto_tree *tree,
1824                     tvbuff_t *tvb, gint start, gint length,
1825                     guint encoding)
1826 {
1827         proto_item *pi;
1828         guint32     value, n;
1829         float       floatval;
1830         double      doubleval;
1831         const char *stringval;
1832         nstime_t    time_stamp;
1833         gboolean    length_error;
1834
1835         switch (new_fi->hfinfo->type) {
1836                 case FT_NONE:
1837                         /* no value to set for FT_NONE */
1838                         break;
1839
1840                 case FT_PROTOCOL:
1841                         proto_tree_set_protocol_tvb(new_fi, tvb, new_fi->hfinfo->name);
1842                         break;
1843
1844                 case FT_BYTES:
1845                         proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
1846                         break;
1847
1848                 case FT_UINT_BYTES:
1849                         /*
1850                          * Map all non-zero values to little-endian for
1851                          * backwards compatibility.
1852                          */
1853                         if (encoding)
1854                                 encoding = ENC_LITTLE_ENDIAN;
1855                         n = get_uint_value(tree, tvb, start, length, encoding);
1856                         proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
1857
1858                         /* Instead of calling proto_item_set_len(), since we don't yet
1859                          * have a proto_item, we set the field_info's length ourselves. */
1860                         new_fi->length = n + length;
1861                         break;
1862
1863                 case FT_BOOLEAN:
1864                         /*
1865                          * Map all non-zero values to little-endian for
1866                          * backwards compatibility.
1867                          */
1868                         if (encoding)
1869                                 encoding = ENC_LITTLE_ENDIAN;
1870                         proto_tree_set_boolean(new_fi,
1871                                 get_uint64_value(tree, tvb, start, length, encoding));
1872                         break;
1873
1874                 /* XXX - make these just FT_UINT? */
1875                 case FT_UINT8:
1876                 case FT_UINT16:
1877                 case FT_UINT24:
1878                 case FT_UINT32:
1879                         /*
1880                          * Map all non-zero values to little-endian for
1881                          * backwards compatibility.
1882                          */
1883                         if (encoding)
1884                                 encoding = ENC_LITTLE_ENDIAN;
1885                         proto_tree_set_uint(new_fi,
1886                                 get_uint_value(tree, tvb, start, length, encoding));
1887                         break;
1888
1889                 case FT_UINT40:
1890                 case FT_UINT48:
1891                 case FT_UINT56:
1892                 case FT_UINT64:
1893                         /*
1894                          * Map all non-zero values to little-endian for
1895                          * backwards compatibility.
1896                          */
1897                         if (encoding)
1898                                 encoding = ENC_LITTLE_ENDIAN;
1899                         proto_tree_set_uint64(new_fi,
1900                                 get_uint64_value(tree, tvb, start, length, encoding));
1901                         break;
1902
1903                 /* XXX - make these just FT_INT? */
1904                 case FT_INT8:
1905                 case FT_INT16:
1906                 case FT_INT24:
1907                 case FT_INT32:
1908                         /*
1909                          * Map all non-zero values to little-endian for
1910                          * backwards compatibility.
1911                          */
1912                         if (encoding)
1913                                 encoding = ENC_LITTLE_ENDIAN;
1914                         proto_tree_set_int(new_fi,
1915                                 get_int_value(tree, tvb, start, length, encoding));
1916                         break;
1917
1918                 case FT_INT40:
1919                 case FT_INT48:
1920                 case FT_INT56:
1921                 case FT_INT64:
1922                         /*
1923                          * Map all non-zero values to little-endian for
1924                          * backwards compatibility.
1925                          */
1926                         if (encoding)
1927                                 encoding = ENC_LITTLE_ENDIAN;
1928                         proto_tree_set_int64(new_fi,
1929                                 get_int64_value(tree, tvb, start, length, encoding));
1930                         break;
1931
1932                 case FT_IPv4:
1933                         /*
1934                          * Map all non-zero values to little-endian for
1935                          * backwards compatibility.
1936                          */
1937                         if (encoding)
1938                                 encoding = ENC_LITTLE_ENDIAN;
1939                         if (length != FT_IPv4_LEN) {
1940                                 length_error = length < FT_IPv4_LEN ? TRUE : FALSE;
1941                                 report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
1942                         }
1943                         value = tvb_get_ipv4(tvb, start);
1944                         /*
1945                          * NOTE: to support code written when
1946                          * proto_tree_add_item() took a gboolean as its
1947                          * last argument, with FALSE meaning "big-endian"
1948                          * and TRUE meaning "little-endian", we treat any
1949                          * non-zero value of "encoding" as meaning
1950                          * "little-endian".
1951                          */
1952                         proto_tree_set_ipv4(new_fi, encoding ? GUINT32_SWAP_LE_BE(value) : value);
1953                         break;
1954
1955                 case FT_IPXNET:
1956                         if (length != FT_IPXNET_LEN) {
1957                                 length_error = length < FT_IPXNET_LEN ? TRUE : FALSE;
1958                                 report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
1959                         }
1960                         proto_tree_set_ipxnet(new_fi,
1961                                 get_uint_value(tree, tvb, start, FT_IPXNET_LEN, ENC_BIG_ENDIAN));
1962                         break;
1963
1964                 case FT_IPv6:
1965                         if (length != FT_IPv6_LEN) {
1966                                 length_error = length < FT_IPv6_LEN ? TRUE : FALSE;
1967                                 report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
1968                         }
1969                         proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
1970                         break;
1971
1972                 case FT_FCWWN:
1973                         if (length != FT_FCWWN_LEN) {
1974                                 length_error = length < FT_FCWWN_LEN ? TRUE : FALSE;
1975                                 report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
1976                         }
1977                         proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
1978                         break;
1979
1980                 case FT_AX25:
1981                         if (length != 7) {
1982                                 length_error = length < 7 ? TRUE : FALSE;
1983                                 report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
1984                         }
1985                         proto_tree_set_ax25_tvb(new_fi, tvb, start);
1986                         break;
1987
1988                 case FT_VINES:
1989                         if (length != VINES_ADDR_LEN) {
1990                                 length_error = length < VINES_ADDR_LEN ? TRUE : FALSE;
1991                                 report_type_length_mismatch(tree, "a Vines address", length, length_error);
1992                         }
1993                         proto_tree_set_vines_tvb(new_fi, tvb, start);
1994                         break;
1995
1996                 case FT_ETHER:
1997                         if (length != FT_ETHER_LEN) {
1998                                 length_error = length < FT_ETHER_LEN ? TRUE : FALSE;
1999                                 report_type_length_mismatch(tree, "a MAC address", length, length_error);
2000                         }
2001                         proto_tree_set_ether_tvb(new_fi, tvb, start);
2002                         break;
2003
2004                 case FT_EUI64:
2005                         /*
2006                          * Map all non-zero values to little-endian for
2007                          * backwards compatibility.
2008                          */
2009                         if (encoding)
2010                                 encoding = ENC_LITTLE_ENDIAN;
2011                         if (length != FT_EUI64_LEN) {
2012                                 length_error = length < FT_EUI64_LEN ? TRUE : FALSE;
2013                                 report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
2014                         }
2015                         proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
2016                         break;
2017                 case FT_GUID:
2018                         /*
2019                          * Map all non-zero values to little-endian for
2020                          * backwards compatibility.
2021                          */
2022                         if (encoding)
2023                                 encoding = ENC_LITTLE_ENDIAN;
2024                         if (length != FT_GUID_LEN) {
2025                                 length_error = length < FT_GUID_LEN ? TRUE : FALSE;
2026                                 report_type_length_mismatch(tree, "a GUID", length, length_error);
2027                         }
2028                         proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
2029                         break;
2030
2031                 case FT_OID:
2032                 case FT_REL_OID:
2033                         proto_tree_set_oid_tvb(new_fi, tvb, start, length);
2034                         break;
2035
2036                 case FT_SYSTEM_ID:
2037                         proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
2038                         break;
2039
2040                 case FT_FLOAT:
2041                         /*
2042                          * NOTE: to support code written when
2043                          * proto_tree_add_item() took a gboolean as its
2044                          * last argument, with FALSE meaning "big-endian"
2045                          * and TRUE meaning "little-endian", we treat any
2046                          * non-zero value of "encoding" as meaning
2047                          * "little-endian".
2048                          *
2049                          * At some point in the future, we might
2050                          * support non-IEEE-binary floating-point
2051                          * formats in the encoding as well
2052                          * (IEEE decimal, System/3x0, VAX).
2053                          */
2054                         if (encoding)
2055                                 encoding = ENC_LITTLE_ENDIAN;
2056                         if (length != 4) {
2057                                 length_error = length < 4 ? TRUE : FALSE;
2058                                 report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
2059                         }
2060                         if (encoding)
2061                                 floatval = tvb_get_letohieee_float(tvb, start);
2062                         else
2063                                 floatval = tvb_get_ntohieee_float(tvb, start);
2064                         proto_tree_set_float(new_fi, floatval);
2065                         break;
2066
2067                 case FT_DOUBLE:
2068                         /*
2069                          * NOTE: to support code written when
2070                          * proto_tree_add_item() took a gboolean as its
2071                          * last argument, with FALSE meaning "big-endian"
2072                          * and TRUE meaning "little-endian", we treat any
2073                          * non-zero value of "encoding" as meaning
2074                          * "little-endian".
2075                          *
2076                          * At some point in the future, we might
2077                          * support non-IEEE-binary floating-point
2078                          * formats in the encoding as well
2079                          * (IEEE decimal, System/3x0, VAX).
2080                          */
2081                         if (encoding == TRUE)
2082                                 encoding = ENC_LITTLE_ENDIAN;
2083                         if (length != 8) {
2084                                 length_error = length < 8 ? TRUE : FALSE;
2085                                 report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
2086                         }
2087                         if (encoding)
2088                                 doubleval = tvb_get_letohieee_double(tvb, start);
2089                         else
2090                                 doubleval = tvb_get_ntohieee_double(tvb, start);
2091                         proto_tree_set_double(new_fi, doubleval);
2092                         break;
2093
2094                 case FT_STRING:
2095                         stringval = get_string_value(wmem_packet_scope(),
2096                             tvb, start, length, &length, encoding);
2097                         proto_tree_set_string(new_fi, stringval);
2098
2099                         /* Instead of calling proto_item_set_len(), since we
2100                          * don't yet have a proto_item, we set the
2101                          * field_info's length ourselves.
2102                          *
2103                          * XXX - our caller can't use that length to
2104                          * advance an offset unless they arrange that
2105                          * there always be a protocol tree into which
2106                          * we're putting this item.
2107                          */
2108                         new_fi->length = length;
2109                         break;
2110
2111                 case FT_STRINGZ:
2112                         stringval = get_stringz_value(wmem_packet_scope(),
2113                             tree, tvb, start, length, &length, encoding);
2114                         proto_tree_set_string(new_fi, stringval);
2115
2116                         /* Instead of calling proto_item_set_len(),
2117                          * since we don't yet have a proto_item, we
2118                          * set the field_info's length ourselves.
2119                          *
2120                          * XXX - our caller can't use that length to
2121                          * advance an offset unless they arrange that
2122                          * there always be a protocol tree into which
2123                          * we're putting this item.
2124                          */
2125                         new_fi->length = length;
2126                         break;
2127
2128                 case FT_UINT_STRING:
2129                         /*
2130                          * NOTE: to support code written when
2131                          * proto_tree_add_item() took a gboolean as its
2132                          * last argument, with FALSE meaning "big-endian"
2133                          * and TRUE meaning "little-endian", if the
2134                          * encoding value is TRUE, treat that as
2135                          * ASCII with a little-endian length.
2136                          *
2137                          * This won't work for code that passes
2138                          * arbitrary non-zero values; that code
2139                          * will need to be fixed.
2140                          */
2141                         if (encoding == TRUE)
2142                                 encoding = ENC_ASCII|ENC_LITTLE_ENDIAN;
2143                         stringval = get_uint_string_value(wmem_packet_scope(),
2144                             tree, tvb, start, length, &length, encoding);
2145                         proto_tree_set_string(new_fi, stringval);
2146
2147                         /* Instead of calling proto_item_set_len(), since we
2148                          * don't yet have a proto_item, we set the
2149                          * field_info's length ourselves.
2150                          *
2151                          * XXX - our caller can't use that length to
2152                          * advance an offset unless they arrange that
2153                          * there always be a protocol tree into which
2154                          * we're putting this item.
2155                          */
2156                         new_fi->length = length;
2157                         break;
2158
2159                 case FT_STRINGZPAD:
2160                         stringval = get_stringzpad_value(wmem_packet_scope(),
2161                             tvb, start, length, &length, encoding);
2162                         proto_tree_set_string(new_fi, stringval);
2163
2164                         /* Instead of calling proto_item_set_len(), since we
2165                          * don't yet have a proto_item, we set the
2166                          * field_info's length ourselves.
2167                          *
2168                          * XXX - our caller can't use that length to
2169                          * advance an offset unless they arrange that
2170                          * there always be a protocol tree into which
2171                          * we're putting this item.
2172                          */
2173                         new_fi->length = length;
2174                         break;
2175
2176                 case FT_ABSOLUTE_TIME:
2177                         /*
2178                          * Absolute times can be in any of a number of
2179                          * formats, and they can be big-endian or
2180                          * little-endian.
2181                          *
2182                          * Historically FT_TIMEs were only timespecs;
2183                          * the only question was whether they were stored
2184                          * in big- or little-endian format.
2185                          *
2186                          * For backwards compatibility, we interpret an
2187                          * encoding of 1 as meaning "little-endian timespec",
2188                          * so that passing TRUE is interpreted as that.
2189                          */
2190                         if (encoding == TRUE)
2191                                 encoding = ENC_TIME_TIMESPEC|ENC_LITTLE_ENDIAN;
2192
2193                         if (length != 8 && length != 4) {
2194                                 length_error = length < 4 ? TRUE : FALSE;
2195                                 report_type_length_mismatch(tree, "an absolute time value", length, length_error);
2196                         }
2197
2198                         get_time_value(tvb, start, length, encoding, &time_stamp, FALSE);
2199
2200                         proto_tree_set_time(new_fi, &time_stamp);
2201                         break;
2202
2203                 case FT_RELATIVE_TIME:
2204                         /*
2205                          * Relative times can be in any of a number of
2206                          * formats, and they can be big-endian or
2207                          * little-endian.
2208                          *
2209                          * Historically FT_TIMEs were only timespecs;
2210                          * the only question was whether they were stored
2211                          * in big- or little-endian format.
2212                          *
2213                          * For backwards compatibility, we interpret an
2214                          * encoding of 1 as meaning "little-endian timespec",
2215                          * so that passing TRUE is interpreted as that.
2216                          */
2217                         if (encoding == TRUE)
2218                                 encoding = ENC_TIME_TIMESPEC|ENC_LITTLE_ENDIAN;
2219
2220                         if (length != 8 && length != 4) {
2221                                 length_error = length < 4 ? TRUE : FALSE;
2222                                 report_type_length_mismatch(tree, "a relative time value", length, length_error);
2223                         }
2224
2225                         get_time_value(tvb, start, length, encoding, &time_stamp, TRUE);
2226
2227                         proto_tree_set_time(new_fi, &time_stamp);
2228                         break;
2229                 case FT_IEEE_11073_SFLOAT:
2230                         if (encoding)
2231                                 encoding = ENC_LITTLE_ENDIAN;
2232                         if (length != 2) {
2233                                 length_error = length < 2 ? TRUE : FALSE;
2234                                 report_type_length_mismatch(tree, "a IEEE 11073 SFLOAT", length, length_error);
2235                         }
2236
2237                         fvalue_set_uinteger(&new_fi->value, tvb_get_guint16(tvb, start, encoding));
2238
2239                         break;
2240                 case FT_IEEE_11073_FLOAT:
2241                         if (encoding)
2242                                 encoding = ENC_LITTLE_ENDIAN;
2243                         if (length != 4) {
2244                                 length_error = length < 4 ? TRUE : FALSE;
2245                                 report_type_length_mismatch(tree, "a IEEE 11073 FLOAT", length, length_error);
2246                         }
2247
2248                         break;
2249                 default:
2250                         g_error("new_fi->hfinfo->type %d (%s) not handled\n",
2251                                         new_fi->hfinfo->type,
2252                                         ftype_name(new_fi->hfinfo->type));
2253                         DISSECTOR_ASSERT_NOT_REACHED();
2254                         break;
2255         }
2256         FI_SET_FLAG(new_fi, (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN);
2257
2258         /* Don't add new node to proto_tree until now so that any exceptions
2259          * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
2260         /* XXX. wouldn't be better to add this item to tree, with some special flag (FI_EXCEPTION?)
2261          *      to know which item caused exception? */
2262         pi = proto_tree_add_node(tree, new_fi);
2263
2264         return pi;
2265 }
2266
2267 proto_item *
2268 proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2269                             const gint start, gint length,
2270                             const guint encoding, gint32 *retval)
2271 {
2272         header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
2273         field_info        *new_fi;
2274         gint32             value;
2275
2276         DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2277
2278         switch (hfinfo->type){
2279         case FT_INT8:
2280         case FT_INT16:
2281         case FT_INT24:
2282         case FT_INT32:
2283                 break;
2284         default:
2285                 DISSECTOR_ASSERT_NOT_REACHED();
2286         }
2287
2288         /* length validation for native number encoding caught by get_uint_value() */
2289         /* length has to be -1 or > 0 regardless of encoding */
2290         if (length < -1 || length == 0)
2291                 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
2292                         "Invalid length %d passed to proto_tree_add_item_ret_int",
2293                         length));
2294
2295         if (encoding & ENC_STRING) {
2296                 REPORT_DISSECTOR_BUG("wrong encoding");
2297         }
2298         /* I believe it's ok if this is called with a NULL tree */
2299         value = get_int_value(tree, tvb, start, length, encoding);
2300
2301         if (retval)
2302                 *retval = value;
2303
2304         CHECK_FOR_NULL_TREE(tree);
2305
2306         TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
2307
2308         new_fi = new_field_info(tree, hfinfo, tvb, start, length);
2309
2310         proto_tree_set_int(new_fi, value);
2311
2312         new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
2313
2314         return proto_tree_add_node(tree, new_fi);
2315 }
2316
2317 proto_item *
2318 proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2319                              const gint start, gint length,
2320                              const guint encoding, guint32 *retval)
2321 {
2322         header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
2323         field_info        *new_fi;
2324         guint32            value;
2325
2326         DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2327
2328         switch (hfinfo->type){
2329         case FT_UINT8:
2330         case FT_UINT16:
2331         case FT_UINT24:
2332         case FT_UINT32:
2333                 break;
2334         default:
2335                 DISSECTOR_ASSERT_NOT_REACHED();
2336         }
2337
2338         /* length validation for native number encoding caught by get_uint_value() */
2339         /* length has to be -1 or > 0 regardless of encoding */
2340         if (length < -1 || length == 0)
2341                 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
2342                         "Invalid length %d passed to proto_tree_add_item_ret_uint",
2343                         length));
2344
2345         if (encoding & ENC_STRING) {
2346                 REPORT_DISSECTOR_BUG("wrong encoding");
2347         }
2348         /* I believe it's ok if this is called with a NULL tree */
2349         value = get_uint_value(tree, tvb, start, length, encoding);
2350
2351         if (retval)
2352                 *retval = value;
2353
2354         CHECK_FOR_NULL_TREE(tree);
2355
2356         TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
2357
2358         new_fi = new_field_info(tree, hfinfo, tvb, start, length);
2359
2360         proto_tree_set_uint(new_fi, value);
2361
2362         new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
2363
2364         return proto_tree_add_node(tree, new_fi);
2365 }
2366
2367 proto_item *
2368 proto_tree_add_item_ret_string_and_length(proto_tree *tree, int hfindex,
2369                                           tvbuff_t *tvb,
2370                                           const gint start, gint length,
2371                                           const guint encoding,
2372                                           wmem_allocator_t *scope,
2373                                           const guint8 **retval,
2374                                           gint *lenretval)
2375 {
2376         header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
2377         field_info        *new_fi;
2378         const guint8      *value;
2379
2380         DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2381
2382         switch (hfinfo->type){
2383         case FT_STRING:
2384                 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
2385                 break;
2386         case FT_STRINGZ:
2387                 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
2388                 break;
2389         case FT_UINT_STRING:
2390                 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
2391                 break;
2392         case FT_STRINGZPAD:
2393                 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
2394                 break;
2395         default:
2396                 DISSECTOR_ASSERT_NOT_REACHED();
2397         }
2398
2399         if (retval)
2400                 *retval = value;
2401
2402         CHECK_FOR_NULL_TREE(tree);
2403
2404         TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
2405
2406         new_fi = new_field_info(tree, hfinfo, tvb, start, length);
2407
2408         proto_tree_set_string(new_fi, value);
2409
2410         new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
2411
2412         return proto_tree_add_node(tree, new_fi);
2413 }
2414
2415 proto_item *
2416 proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2417                                const gint start, gint length,
2418                                const guint encoding, wmem_allocator_t *scope,
2419                                const guint8 **retval)
2420 {
2421         return proto_tree_add_item_ret_string_and_length(tree, hfindex,
2422             tvb, start, length, encoding, scope, retval, &length);
2423 }
2424
2425 /*
2426  * Validates that field length bytes are available starting from
2427  * start (pos/neg). Throws an exception if they aren't.
2428  */
2429 static void
2430 test_length(header_field_info *hfinfo, tvbuff_t *tvb,
2431             gint start, gint length)
2432 {
2433         gint size = length;
2434
2435         if (!tvb)
2436                 return;
2437
2438         if (hfinfo->type == FT_STRINGZ) {
2439                 /* If we're fetching until the end of the TVB, only validate
2440                  * that the offset is within range.
2441                  */
2442                 if (length == -1)
2443                         size = 0;
2444         }
2445
2446         tvb_ensure_bytes_exist(tvb, start, size);
2447 }
2448
2449 /* Gets data from tvbuff, adds it to proto_tree, increments offset,
2450    and returns proto_item* */
2451 proto_item *
2452 ptvcursor_add(ptvcursor_t *ptvc, int hfindex, gint length,
2453               const guint encoding)
2454 {
2455         field_info        *new_fi;
2456         header_field_info *hfinfo;
2457         gint               item_length;
2458         int                offset;
2459
2460         offset = ptvc->offset;
2461         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2462         get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length);
2463         test_length(hfinfo, ptvc->tvb, offset, item_length);
2464
2465         ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
2466             item_length, encoding);
2467
2468         CHECK_FOR_NULL_TREE(ptvc->tree);
2469
2470         /* Coast clear. Try and fake it */
2471         TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo);
2472
2473         new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
2474
2475         return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
2476                 offset, length, encoding);
2477 }
2478
2479 /* Add an item to a proto_tree, using the text label registered to that item;
2480    the item is extracted from the tvbuff handed to it. */
2481 proto_item *
2482 proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
2483                         const gint start, gint length, const guint encoding)
2484 {
2485         field_info        *new_fi;
2486         gint              item_length;
2487
2488         DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2489
2490         get_hfi_length(hfinfo, tvb, start, &length, &item_length);
2491         test_length(hfinfo, tvb, start, item_length);
2492
2493         CHECK_FOR_NULL_TREE(tree);
2494
2495         TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
2496
2497         new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
2498
2499         return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
2500 }
2501
2502 proto_item *
2503 proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2504                     const gint start, gint length, const guint encoding)
2505 {
2506         register header_field_info *hfinfo;
2507
2508         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2509         return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
2510 }
2511
2512 /* Add an item to a proto_tree, using the text label registered to that item;
2513    the item is extracted from the tvbuff handed to it.
2514
2515    Return the length of the item through the pointer. */
2516 proto_item *
2517 proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
2518                                    tvbuff_t *tvb, const gint start,
2519                                    gint length, const guint encoding,
2520                                    gint *lenretval)
2521 {
2522         field_info        *new_fi;
2523         gint              item_length;
2524         proto_item       *item;
2525
2526         DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2527
2528         get_hfi_length(hfinfo, tvb, start, &length, &item_length);
2529         test_length(hfinfo, tvb, start, item_length);
2530
2531         if (!tree) {
2532                 /*
2533                  * We need to get the correct item length here.
2534                  * That's normally done by proto_tree_new_item(),
2535                  * but we won't be calling it.
2536                  */
2537                 *lenretval = get_full_length(hfinfo, tvb, start, length,
2538                     item_length, encoding);
2539                 return NULL;
2540         }
2541
2542         TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
2543
2544         new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
2545
2546         item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
2547         *lenretval = new_fi->length;
2548         return item;
2549 }
2550
2551 proto_item *
2552 proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2553                                const gint start, gint length,
2554                                const guint encoding, gint *lenretval)
2555 {
2556         register header_field_info *hfinfo;
2557
2558         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2559         return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, lenretval);
2560 }
2561
2562 /* which FT_ types can use proto_tree_add_bytes_item() */
2563 static inline gboolean
2564 validate_proto_tree_add_bytes_ftype(const enum ftenum type)
2565 {
2566         return (type == FT_BYTES      ||
2567                 type == FT_UINT_BYTES ||
2568                 type == FT_OID        ||
2569                 type == FT_REL_OID    ||
2570                 type == FT_SYSTEM_ID  );
2571 }
2572
2573 /* Note: this does no validation that the byte array of an FT_OID or
2574    FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
2575    so I think it's ok to continue not validating it?
2576  */
2577 proto_item *
2578 proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2579                            const gint start, gint length, const guint encoding,
2580                            GByteArray *retval, gint *endoff, gint *err)
2581 {
2582         field_info        *new_fi;
2583         GByteArray        *bytes = retval;
2584         GByteArray        *created_bytes = NULL;
2585         gint               saved_err = 0;
2586         guint32            n = 0;
2587         header_field_info *hfinfo;
2588         gboolean           generate = (bytes || tree) ? TRUE : FALSE;
2589
2590         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2591
2592         DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2593
2594         DISSECTOR_ASSERT_HINT(validate_proto_tree_add_bytes_ftype(hfinfo->type),
2595                 "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type");
2596
2597         /* length has to be -1 or > 0 regardless of encoding */
2598         /* invalid FT_UINT_BYTES length is caught in get_uint_value() */
2599         if (length < -1 || length == 0) {
2600                 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
2601                     "Invalid length %d passed to proto_tree_add_bytes_item for %s",
2602                     length, ftype_name(hfinfo->type)));
2603         }
2604
2605         if (encoding & ENC_STR_NUM) {
2606                 REPORT_DISSECTOR_BUG("Decoding number strings for byte arrays is not supported");
2607         }
2608
2609         if (generate && (encoding & ENC_STR_HEX)) {
2610                 if (hfinfo->type == FT_UINT_BYTES) {
2611                         /* can't decode FT_UINT_BYTES from strings */
2612                         REPORT_DISSECTOR_BUG("proto_tree_add_bytes_item called for "
2613                             "FT_UINT_BYTES type, but as ENC_STR_HEX");
2614                 }
2615
2616                 if (!bytes) {
2617                         /* caller doesn't care about return value, but we need it to
2618                            call tvb_get_string_bytes() and set the tree later */
2619                         bytes = created_bytes = g_byte_array_new();
2620                 }
2621
2622                 /* bytes might be NULL after this, but can't add expert error until later */
2623                 bytes = tvb_get_string_bytes(tvb, start, length, encoding, bytes, endoff);
2624
2625                 /* grab the errno now before it gets overwritten */
2626                 saved_err = errno;
2627         }
2628         else if (generate) {
2629                 tvb_ensure_bytes_exist(tvb, start, length);
2630
2631                 if (!bytes) {
2632                         /* caller doesn't care about return value, but we need it to
2633                            call tvb_get_string_bytes() and set the tree later */
2634                         bytes = created_bytes = g_byte_array_new();
2635                 }
2636
2637                 if (hfinfo->type == FT_UINT_BYTES) {
2638                         n = length; /* n is now the "header" length */
2639                         length = get_uint_value(tree, tvb, start, n, encoding);
2640                         /* length is now the value's length; only store the value in the array */
2641                         g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
2642                 }
2643                 else if (length > 0) {
2644                         g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
2645                 }
2646
2647                 if (endoff)
2648                     *endoff = start + n + length;
2649         }
2650
2651         if (err) *err = saved_err;
2652
2653         CHECK_FOR_NULL_TREE_AND_FREE(tree,
2654                 {
2655                     if (created_bytes)
2656                         g_byte_array_free(created_bytes, TRUE);
2657                     created_bytes = NULL;
2658                     bytes = NULL;
2659                 } );
2660
2661         TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfinfo->id, hfinfo,
2662                 {
2663                     if (created_bytes)
2664                         g_byte_array_free(created_bytes, TRUE);
2665                     created_bytes = NULL;
2666                     bytes = NULL;
2667                 } );
2668
2669         /* n will be zero except when it's a FT_UINT_BYTES */
2670         new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
2671
2672         if (encoding & ENC_STRING) {
2673                 if (saved_err == ERANGE)
2674                     expert_add_info(NULL, tree, &ei_number_string_decoding_erange_error);
2675                 else if (!bytes || saved_err != 0)
2676                     expert_add_info(NULL, tree, &ei_number_string_decoding_failed_error);
2677
2678                 if (bytes)
2679                     proto_tree_set_bytes_gbytearray(new_fi, bytes);
2680                 else
2681                     proto_tree_set_bytes(new_fi, NULL, 0);
2682
2683                 if (created_bytes)
2684                     g_byte_array_free(created_bytes, TRUE);
2685         }
2686         else {
2687                 /* n will be zero except when it's a FT_UINT_BYTES */
2688                 proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
2689
2690                 FI_SET_FLAG(new_fi,
2691                         (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN);
2692         }
2693
2694         return proto_tree_add_node(tree, new_fi);
2695 }
2696
2697
2698 proto_item *
2699 proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2700                            const gint start, gint length, const guint encoding,
2701                            nstime_t *retval, gint *endoff, gint *err)
2702 {
2703         field_info        *new_fi;
2704         nstime_t           time_stamp;
2705         gint               saved_err = 0;
2706         header_field_info *hfinfo;
2707
2708         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2709
2710         DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
2711
2712         DISSECTOR_ASSERT_FIELD_TYPE_IS_TIME(hfinfo);
2713
2714         /* length has to be -1 or > 0 regardless of encoding */
2715         if (length < -1 || length == 0) {
2716                 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
2717                     "Invalid length %d passed to proto_tree_add_time_item", length));
2718         }
2719
2720         time_stamp.secs  = 0;
2721         time_stamp.nsecs = 0;
2722
2723         if (encoding & ENC_STR_TIME_MASK) {
2724                 tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff);
2725                 /* grab the errno now before it gets overwritten */
2726                 saved_err = errno;
2727         }
2728         else {
2729                 const gboolean is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? TRUE : FALSE;
2730
2731                 if (length != 8 && length != 4) {
2732                         const gboolean length_error = length < 4 ? TRUE : FALSE;
2733                         if (is_relative)
2734                             report_type_length_mismatch(tree, "a relative time value", length, length_error);
2735                         else
2736                             report_type_length_mismatch(tree, "an absolute time value", length, length_error);
2737                 }
2738
2739                 tvb_ensure_bytes_exist(tvb, start, length);
2740                 get_time_value(tvb, start, length, encoding, &time_stamp, is_relative);
2741                 if (endoff) *endoff = length;
2742         }
2743
2744         if (err) *err = saved_err;
2745
2746         if (retval) {
2747                 retval->secs  = time_stamp.secs;
2748                 retval->nsecs = time_stamp.nsecs;
2749         }
2750
2751         CHECK_FOR_NULL_TREE(tree);
2752
2753         TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
2754
2755         new_fi = new_field_info(tree, hfinfo, tvb, start, length);
2756
2757         proto_tree_set_time(new_fi, &time_stamp);
2758
2759         if (encoding & ENC_STRING) {
2760                 if (saved_err == ERANGE)
2761                     expert_add_info(NULL, tree, &ei_number_string_decoding_erange_error);
2762                 else if (saved_err == EDOM)
2763                     expert_add_info(NULL, tree, &ei_number_string_decoding_failed_error);
2764         }
2765         else {
2766                 FI_SET_FLAG(new_fi,
2767                         (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN);
2768         }
2769
2770         return proto_tree_add_node(tree, new_fi);
2771 }
2772
2773 /* Add a FT_NONE to a proto_tree */
2774 proto_item *
2775 proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
2776                            const gint start, gint length, const char *format,
2777                            ...)
2778 {
2779         proto_item        *pi;
2780         va_list            ap;
2781         header_field_info *hfinfo;
2782
2783         CHECK_FOR_NULL_TREE(tree);
2784
2785         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2786
2787         DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_NONE);
2788
2789         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2790
2791         TRY_TO_FAKE_THIS_REPR(pi);
2792
2793         va_start(ap, format);
2794         proto_tree_set_representation(pi, format, ap);
2795         va_end(ap);
2796
2797         /* no value to set for FT_NONE */
2798         return pi;
2799 }
2800
2801 /* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
2802  * offset, and returns proto_item* */
2803 proto_item *
2804 ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, gint length,
2805                          const guint encoding)
2806 {
2807         proto_item *item;
2808
2809         item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
2810                                    length, encoding);
2811
2812         return item;
2813 }
2814
2815 /* Advance the ptvcursor's offset within its tvbuff without
2816  * adding anything to the proto_tree. */
2817 void
2818 ptvcursor_advance(ptvcursor_t* ptvc, gint length)
2819 {
2820         ptvc->offset += length;
2821 }
2822
2823
2824 static void
2825 proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data)
2826 {
2827         fvalue_set_protocol(&fi->value, tvb, field_data);
2828 }
2829
2830 /* Add a FT_PROTOCOL to a proto_tree */
2831 proto_item *
2832 proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2833                                gint start, gint length, const char *format, ...)
2834 {
2835         proto_item        *pi;
2836         va_list            ap;
2837         header_field_info *hfinfo;
2838         gchar* protocol_rep;
2839
2840         CHECK_FOR_NULL_TREE(tree);
2841
2842         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2843
2844         DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_PROTOCOL);
2845
2846         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2847
2848         va_start(ap, format);
2849         protocol_rep = g_strdup_vprintf(format, ap);
2850         proto_tree_set_protocol_tvb(PNODE_FINFO(pi), (start == 0 ? tvb : tvb_new_subset_length(tvb, start, length)), protocol_rep);
2851         g_free(protocol_rep);
2852         va_end(ap);
2853
2854         TRY_TO_FAKE_THIS_REPR(pi);
2855
2856         va_start(ap, format);
2857         proto_tree_set_representation(pi, format, ap);
2858         va_end(ap);
2859
2860         return pi;
2861 }
2862
2863 /* Add a FT_BYTES to a proto_tree */
2864 proto_item *
2865 proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2866                      gint length, const guint8 *start_ptr)
2867 {
2868         proto_item        *pi;
2869         header_field_info *hfinfo;
2870         gint              item_length;
2871
2872         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2873         get_hfi_length(hfinfo, tvb, start, &length, &item_length);
2874         test_length(hfinfo, tvb, start, item_length);
2875
2876         CHECK_FOR_NULL_TREE(tree);
2877
2878         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2879
2880         DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BYTES);
2881
2882         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2883         proto_tree_set_bytes(PNODE_FINFO(pi), start_ptr, length);
2884
2885         return pi;
2886 }
2887
2888 /* Add a FT_BYTES to a proto_tree */
2889 proto_item *
2890 proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2891              gint tvbuff_length, const guint8 *start_ptr, gint ptr_length)
2892 {
2893         proto_item    *pi;
2894         header_field_info *hfinfo;
2895         gint          item_length;
2896
2897         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2898         get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length);
2899         test_length(hfinfo, tvb, start, item_length);
2900
2901         CHECK_FOR_NULL_TREE(tree);
2902
2903         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2904
2905         DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BYTES);
2906
2907         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
2908         proto_tree_set_bytes(PNODE_FINFO(pi), start_ptr, ptr_length);
2909
2910         return pi;
2911 }
2912
2913 proto_item *
2914 proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2915                                   gint start, gint length,
2916                                   const guint8 *start_ptr,
2917                                   const char *format, ...)
2918 {
2919         proto_item        *pi;
2920         va_list            ap;
2921         header_field_info *hfinfo;
2922         gint              item_length;
2923
2924         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2925         get_hfi_length(hfinfo, tvb, start, &length, &item_length);
2926         test_length(hfinfo, tvb, start, item_length);
2927
2928         CHECK_FOR_NULL_TREE(tree);
2929
2930         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2931
2932         if (start_ptr)
2933                 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length,
2934                                           start_ptr);
2935         else
2936                 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length,
2937                                           tvb_get_ptr(tvb, start, length));
2938
2939         va_start(ap, format);
2940         proto_tree_set_representation_value(pi, format, ap);
2941         va_end(ap);
2942
2943         return pi;
2944 }
2945
2946 proto_item *
2947 proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2948                             gint start, gint length, const guint8 *start_ptr,
2949                             const char *format, ...)
2950 {
2951         proto_item        *pi;
2952         va_list            ap;
2953         header_field_info *hfinfo;
2954         gint              item_length;
2955
2956         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2957         get_hfi_length(hfinfo, tvb, start, &length, &item_length);
2958         test_length(hfinfo, tvb, start, item_length);
2959
2960         CHECK_FOR_NULL_TREE(tree);
2961
2962         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2963
2964         if (start_ptr)
2965                 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length,
2966                                           start_ptr);
2967         else
2968                 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length,
2969                                           tvb_get_ptr(tvb, start, length));
2970
2971         TRY_TO_FAKE_THIS_REPR(pi);
2972
2973         va_start(ap, format);
2974         proto_tree_set_representation(pi, format, ap);
2975         va_end(ap);
2976
2977         return pi;
2978 }
2979
2980 static void
2981 proto_tree_set_bytes(field_info *fi, const guint8* start_ptr, gint length)
2982 {
2983         GByteArray *bytes;
2984
2985         DISSECTOR_ASSERT(start_ptr != NULL || length == 0);
2986
2987         bytes = g_byte_array_new();
2988         if (length > 0) {
2989                 g_byte_array_append(bytes, start_ptr, length);
2990         }
2991         fvalue_set_byte_array(&fi->value, bytes);
2992 }
2993
2994
2995 static void
2996 proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, gint offset, gint length)
2997 {
2998         proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
2999 }
3000
3001 static void
3002 proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
3003 {
3004         GByteArray *bytes;
3005
3006         DISSECTOR_ASSERT(value != NULL);
3007
3008         bytes = byte_array_dup(value);
3009
3010         fvalue_set_byte_array(&fi->value, bytes);
3011 }
3012
3013 /* Add a FT_*TIME to a proto_tree */
3014 proto_item *
3015 proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3016                     gint length, const nstime_t *value_ptr)
3017 {
3018         proto_item        *pi;
3019         header_field_info *hfinfo;
3020
3021         CHECK_FOR_NULL_TREE(tree);
3022
3023         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3024
3025         DISSECTOR_ASSERT_FIELD_TYPE_IS_TIME(hfinfo);
3026
3027         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3028         proto_tree_set_time(PNODE_FINFO(pi), value_ptr);
3029
3030         return pi;
3031 }
3032
3033 proto_item *
3034 proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3035                                  gint start, gint length, nstime_t *value_ptr,
3036                                  const char *format, ...)
3037 {
3038         proto_item        *pi;
3039         va_list            ap;
3040
3041         pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
3042         if (pi != tree) {
3043                 va_start(ap, format);
3044                 proto_tree_set_representation_value(pi, format, ap);
3045                 va_end(ap);
3046         }
3047
3048         return pi;
3049 }
3050
3051 proto_item *
3052 proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3053                            gint start, gint length, nstime_t *value_ptr,
3054                            const char *format, ...)
3055 {
3056         proto_item        *pi;
3057         va_list            ap;
3058
3059         pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
3060         if (pi != tree) {
3061                 TRY_TO_FAKE_THIS_REPR(pi);
3062
3063                 va_start(ap, format);
3064                 proto_tree_set_representation(pi, format, ap);
3065                 va_end(ap);
3066         }
3067
3068         return pi;
3069 }
3070
3071 /* Set the FT_*TIME value */
3072 static void
3073 proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
3074 {
3075         DISSECTOR_ASSERT(value_ptr != NULL);
3076
3077         fvalue_set_time(&fi->value, value_ptr);
3078 }
3079
3080 /* Add a FT_IPXNET to a proto_tree */
3081 proto_item *
3082 proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3083                       gint length, guint32 value)
3084 {
3085         proto_item        *pi;
3086         header_field_info *hfinfo;
3087
3088         CHECK_FOR_NULL_TREE(tree);
3089
3090         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3091
3092         DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_IPXNET);
3093
3094         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3095         proto_tree_set_ipxnet(PNODE_FINFO(pi), value);
3096
3097         return pi;
3098 }
3099
3100 proto_item *
3101 proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3102                                    gint start, gint length, guint32 value,
3103                                    const char *format, ...)
3104 {
3105         proto_item        *pi;
3106         va_list            ap;
3107
3108         pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
3109         if (pi != tree) {
3110                 va_start(ap, format);
3111                 proto_tree_set_representation_value(pi, format, ap);
3112                 va_end(ap);
3113         }
3114
3115         return pi;
3116 }
3117
3118 proto_item *
3119 proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3120                              gint start, gint length, guint32 value,
3121                              const char *format, ...)
3122 {
3123         proto_item        *pi;
3124         va_list            ap;
3125
3126         pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
3127         if (pi != tree) {
3128                 TRY_TO_FAKE_THIS_REPR(pi);
3129
3130                 va_start(ap, format);
3131                 proto_tree_set_representation(pi, format, ap);
3132                 va_end(ap);
3133         }
3134
3135         return pi;
3136 }
3137
3138 /* Set the FT_IPXNET value */
3139 static void
3140 proto_tree_set_ipxnet(field_info *fi, guint32 value)
3141 {
3142         fvalue_set_uinteger(&fi->value, value);
3143 }
3144
3145 /* Add a FT_IPv4 to a proto_tree */
3146 proto_item *
3147 proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3148                     gint length, guint32 value)
3149 {
3150         proto_item        *pi;
3151         header_field_info *hfinfo;
3152
3153         CHECK_FOR_NULL_TREE(tree);
3154
3155         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3156
3157         DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_IPv4);
3158
3159         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3160         proto_tree_set_ipv4(PNODE_FINFO(pi), value);
3161
3162         return pi;
3163 }
3164
3165 proto_item *
3166 proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3167                                  gint start, gint length, guint32 value,
3168                                  const char *format, ...)
3169 {
3170         proto_item        *pi;
3171         va_list            ap;
3172
3173         pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
3174         if (pi != tree) {
3175                 va_start(ap, format);
3176                 proto_tree_set_representation_value(pi, format, ap);
3177                 va_end(ap);
3178         }
3179
3180         return pi;
3181 }
3182
3183 proto_item *
3184 proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3185                            gint start, gint length, guint32 value,
3186                            const char *format, ...)
3187 {
3188         proto_item        *pi;
3189         va_list            ap;
3190
3191         pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
3192         if (pi != tree) {
3193                 TRY_TO_FAKE_THIS_REPR(pi);
3194
3195                 va_start(ap, format);
3196                 proto_tree_set_representation(pi, format, ap);
3197                 va_end(ap);
3198         }
3199
3200         return pi;
3201 }
3202
3203 /* Set the FT_IPv4 value */
3204 static void
3205 proto_tree_set_ipv4(field_info *fi, guint32 value)
3206 {
3207         fvalue_set_uinteger(&fi->value, value);
3208 }
3209
3210 /* Add a FT_IPv6 to a proto_tree */
3211 proto_item *
3212 proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3213                     gint length, const struct e_in6_addr *value_ptr)
3214 {
3215         proto_item        *pi;
3216         header_field_info *hfinfo;
3217
3218         CHECK_FOR_NULL_TREE(tree);
3219
3220         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3221
3222         DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_IPv6);
3223
3224         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3225         proto_tree_set_ipv6(PNODE_FINFO(pi), value_ptr->bytes);
3226
3227         return pi;
3228 }
3229
3230 proto_item *
3231 proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3232                                  gint start, gint length,
3233                                  const struct e_in6_addr *value_ptr,
3234                                  const char *format, ...)
3235 {
3236         proto_item        *pi;
3237         va_list            ap;
3238
3239         pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
3240         if (pi != tree) {
3241                 va_start(ap, format);
3242                 proto_tree_set_representation_value(pi, format, ap);
3243                 va_end(ap);
3244         }
3245
3246         return pi;
3247 }
3248
3249 proto_item *
3250 proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3251                            gint start, gint length,
3252                            const struct e_in6_addr *value_ptr,
3253                            const char *format, ...)
3254 {
3255         proto_item        *pi;
3256         va_list            ap;
3257
3258         pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
3259         if (pi != tree) {
3260                 TRY_TO_FAKE_THIS_REPR(pi);
3261
3262                 va_start(ap, format);
3263                 proto_tree_set_representation(pi, format, ap);
3264                 va_end(ap);
3265         }
3266
3267         return pi;
3268 }
3269
3270 /* Set the FT_IPv6 value */
3271 static void
3272 proto_tree_set_ipv6(field_info *fi, const guint8* value_ptr)
3273 {
3274         DISSECTOR_ASSERT(value_ptr != NULL);
3275         fvalue_set_bytes(&fi->value, value_ptr);
3276 }
3277
3278 static void
3279 proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
3280 {
3281         proto_tree_set_ipv6(fi, tvb_get_ptr(tvb, start, length));
3282 }
3283
3284 /* Set the FT_FCWWN value */
3285 static void
3286 proto_tree_set_fcwwn(field_info *fi, const guint8* value_ptr)
3287 {
3288         DISSECTOR_ASSERT(value_ptr != NULL);
3289         fvalue_set_bytes(&fi->value, value_ptr);
3290 }
3291
3292 static void
3293 proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
3294 {
3295         proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
3296 }
3297
3298 /* Add a FT_GUID to a proto_tree */
3299 proto_item *
3300 proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3301                     gint length, const e_guid_t *value_ptr)
3302 {
3303         proto_item        *pi;
3304         header_field_info *hfinfo;
3305
3306         CHECK_FOR_NULL_TREE(tree);
3307
3308         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3309
3310         DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_GUID);
3311
3312         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3313         proto_tree_set_guid(PNODE_FINFO(pi), value_ptr);
3314
3315         return pi;
3316 }
3317
3318 proto_item *
3319 proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3320                                  gint start, gint length,
3321                                  const e_guid_t *value_ptr,
3322                                  const char *format, ...)
3323 {
3324         proto_item        *pi;
3325         va_list            ap;
3326
3327         pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
3328         if (pi != tree) {
3329                 va_start(ap, format);
3330                 proto_tree_set_representation_value(pi, format, ap);
3331                 va_end(ap);
3332         }
3333
3334         return pi;
3335 }
3336
3337 proto_item *
3338 proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3339                            gint start, gint length, const e_guid_t *value_ptr,
3340                            const char *format, ...)
3341 {
3342         proto_item        *pi;
3343         va_list            ap;
3344
3345         pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
3346         if (pi != tree) {
3347                 TRY_TO_FAKE_THIS_REPR(pi);
3348
3349                 va_start(ap, format);
3350                 proto_tree_set_representation(pi, format, ap);
3351                 va_end(ap);
3352         }
3353
3354         return pi;
3355 }
3356
3357 /* Set the FT_GUID value */
3358 static void
3359 proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
3360 {
3361         DISSECTOR_ASSERT(value_ptr != NULL);
3362         fvalue_set_guid(&fi->value, value_ptr);
3363 }
3364
3365 static void
3366 proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, gint start,
3367                         const guint encoding)
3368 {
3369         e_guid_t guid;
3370
3371         tvb_get_guid(tvb, start, &guid, encoding);
3372         proto_tree_set_guid(fi, &guid);
3373 }
3374
3375 /* Add a FT_OID to a proto_tree */
3376 proto_item *
3377 proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3378                    gint length, const guint8* value_ptr)
3379 {
3380         proto_item        *pi;
3381         header_field_info *hfinfo;
3382
3383         CHECK_FOR_NULL_TREE(tree);
3384
3385         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3386
3387         DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_OID);
3388
3389         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3390         proto_tree_set_oid(PNODE_FINFO(pi), value_ptr, length);
3391
3392         return pi;
3393 }
3394
3395 proto_item *
3396 proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3397                                 gint start, gint length,
3398                                 const guint8* value_ptr,
3399                                 const char *format, ...)
3400 {
3401         proto_item        *pi;
3402         va_list            ap;
3403
3404         pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
3405         if (pi != tree) {
3406                 va_start(ap, format);
3407                 proto_tree_set_representation_value(pi, format, ap);
3408                 va_end(ap);
3409         }
3410
3411         return pi;
3412 }
3413
3414 proto_item *
3415 proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3416                           gint start, gint length, const guint8* value_ptr,
3417                           const char *format, ...)
3418 {
3419         proto_item        *pi;
3420         va_list            ap;
3421
3422         pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
3423         if (pi != tree) {
3424                 TRY_TO_FAKE_THIS_REPR(pi);
3425
3426                 va_start(ap, format);
3427                 proto_tree_set_representation(pi, format, ap);
3428                 va_end(ap);
3429         }
3430
3431         return pi;
3432 }
3433
3434 /* Set the FT_OID value */
3435 static void
3436 proto_tree_set_oid(field_info *fi, const guint8* value_ptr, gint length)
3437 {
3438         GByteArray *bytes;
3439
3440         DISSECTOR_ASSERT(value_ptr != NULL || length == 0);
3441
3442         bytes = g_byte_array_new();
3443         if (length > 0) {
3444                 g_byte_array_append(bytes, value_ptr, length);
3445         }
3446         fvalue_set_byte_array(&fi->value, bytes);
3447 }
3448
3449 static void
3450 proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
3451 {
3452         proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
3453 }
3454
3455 /* Set the FT_SYSTEM_ID value */
3456 static void
3457 proto_tree_set_system_id(field_info *fi, const guint8* value_ptr, gint length)
3458 {
3459         GByteArray *bytes;
3460
3461         DISSECTOR_ASSERT(value_ptr != NULL || length == 0);
3462
3463         bytes = g_byte_array_new();
3464         if (length > 0) {
3465                 g_byte_array_append(bytes, value_ptr, length);
3466         }
3467         fvalue_set_byte_array(&fi->value, bytes);
3468 }
3469
3470 static void
3471 proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
3472 {
3473         proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
3474 }
3475
3476 /* Add a FT_STRING, FT_STRINGZ, or FT_STRINGZPAD to a proto_tree. Creates
3477  * own copy of string, and frees it when the proto_tree is destroyed. */
3478 proto_item *
3479 proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3480                       gint length, const char* value)
3481 {
3482         proto_item        *pi;
3483         header_field_info *hfinfo;
3484
3485         CHECK_FOR_NULL_TREE(tree);
3486
3487         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3488
3489         DISSECTOR_ASSERT_FIELD_TYPE_IS_STRING(hfinfo);
3490
3491         if (hfinfo->display == STR_UNICODE) {
3492                 DISSECTOR_ASSERT(g_utf8_validate(value, -1, NULL));
3493         }
3494
3495         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3496         DISSECTOR_ASSERT(length >= 0);
3497         proto_tree_set_string(PNODE_FINFO(pi), value);
3498
3499         return pi;
3500 }
3501
3502 proto_item *
3503 proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3504                                    gint start, gint length, const char* value,
3505                                    const char *format,
3506                                    ...)
3507 {
3508         proto_item        *pi;
3509         va_list            ap;
3510
3511         pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
3512         if (pi != tree) {
3513                 va_start(ap, format);
3514                 proto_tree_set_representation_value(pi, format, ap);
3515                 va_end(ap);
3516         }
3517
3518         return pi;
3519 }
3520
3521 proto_item *
3522 proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3523                              gint start, gint length, const char* value,
3524                              const char *format, ...)
3525 {
3526         proto_item        *pi;
3527         va_list            ap;
3528
3529         pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
3530         if (pi != tree) {
3531                 TRY_TO_FAKE_THIS_REPR(pi);
3532
3533                 va_start(ap, format);
3534                 proto_tree_set_representation(pi, format, ap);
3535                 va_end(ap);
3536         }
3537
3538         return pi;
3539 }
3540
3541 /* Set the FT_STRING value */
3542 static void
3543 proto_tree_set_string(field_info *fi, const char* value)
3544 {
3545         if (value) {
3546                 fvalue_set_string(&fi->value, value);
3547         } else {
3548                 fvalue_set_string(&fi->value, "[ Null ]");
3549         }
3550 }
3551
3552 /* Set the FT_AX25 value */
3553 static void
3554 proto_tree_set_ax25(field_info *fi, const guint8* value)
3555 {
3556         fvalue_set_bytes(&fi->value, value);
3557 }
3558
3559 static void
3560 proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, gint start)
3561 {
3562         proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
3563 }
3564
3565 /* Set the FT_VINES value */
3566 static void
3567 proto_tree_set_vines(field_info *fi, const guint8* value)
3568 {
3569         fvalue_set_bytes(&fi->value, value);
3570 }
3571
3572 static void
3573 proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, gint start)
3574 {
3575         proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN));
3576 }
3577
3578 /* Add a FT_ETHER to a proto_tree */
3579 proto_item *
3580 proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3581                      gint length, const guint8* value)
3582 {
3583         proto_item        *pi;
3584         header_field_info *hfinfo;
3585
3586         CHECK_FOR_NULL_TREE(tree);
3587
3588         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3589
3590         DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_ETHER);
3591
3592         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3593         proto_tree_set_ether(PNODE_FINFO(pi), value);
3594
3595         return pi;
3596 }
3597
3598 proto_item *
3599 proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3600                                   gint start, gint length, const guint8* value,
3601                                   const char *format, ...)
3602 {
3603         proto_item        *pi;
3604         va_list            ap;
3605
3606         pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
3607         if (pi != tree) {
3608                 va_start(ap, format);
3609                 proto_tree_set_representation_value(pi, format, ap);
3610                 va_end(ap);
3611         }
3612
3613         return pi;
3614 }
3615
3616 proto_item *
3617 proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3618                             gint start, gint length, const guint8* value,
3619                             const char *format, ...)
3620 {
3621         proto_item        *pi;
3622         va_list            ap;
3623
3624         pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
3625         if (pi != tree) {
3626                 TRY_TO_FAKE_THIS_REPR(pi);
3627
3628                 va_start(ap, format);
3629                 proto_tree_set_representation(pi, format, ap);
3630                 va_end(ap);
3631         }
3632
3633         return pi;
3634 }
3635
3636 /* Set the FT_ETHER value */
3637 static void
3638 proto_tree_set_ether(field_info *fi, const guint8* value)
3639 {
3640         fvalue_set_bytes(&fi->value, value);
3641 }
3642
3643 static void
3644 proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, gint start)
3645 {
3646         proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN));
3647 }
3648
3649 /* Add a FT_BOOLEAN to a proto_tree */
3650 proto_item *
3651 proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3652                        gint length, guint32 value)
3653 {
3654         proto_item        *pi;
3655         header_field_info *hfinfo;
3656
3657         CHECK_FOR_NULL_TREE(tree);
3658
3659         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3660
3661         DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BOOLEAN);
3662
3663         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3664         proto_tree_set_boolean(PNODE_FINFO(pi), value);
3665
3666         return pi;
3667 }
3668
3669 proto_item *
3670 proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
3671                                     tvbuff_t *tvb, gint start, gint length,
3672                                     guint32 value, const char *format, ...)
3673 {
3674         proto_item        *pi;
3675         va_list            ap;
3676
3677         pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
3678         if (pi != tree) {
3679                 va_start(ap, format);
3680                 proto_tree_set_representation_value(pi, format, ap);
3681                 va_end(ap);
3682         }
3683
3684         return pi;
3685 }
3686
3687 proto_item *
3688 proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3689                               gint start, gint length, guint32 value,
3690                               const char *format, ...)
3691 {
3692         proto_item        *pi;
3693         va_list            ap;
3694
3695         pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
3696         if (pi != tree) {
3697                 TRY_TO_FAKE_THIS_REPR(pi);
3698
3699                 va_start(ap, format);
3700                 proto_tree_set_representation(pi, format, ap);
3701                 va_end(ap);
3702         }
3703
3704         return pi;
3705 }
3706
3707 static proto_item *
3708 proto_tree_add_boolean64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3709                          gint length, guint64 value)
3710 {
3711         proto_item        *pi;
3712         header_field_info *hfinfo;
3713
3714         CHECK_FOR_NULL_TREE(tree);
3715
3716         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3717
3718         DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BOOLEAN);
3719
3720         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3721         proto_tree_set_boolean(PNODE_FINFO(pi), value);
3722
3723         return pi;
3724 }
3725
3726 /* Set the FT_BOOLEAN value */
3727 static void
3728 proto_tree_set_boolean(field_info *fi, guint64 value)
3729 {
3730         proto_tree_set_uint64(fi, value);
3731 }
3732
3733 /* Generate, into "buf", a string showing the bits of a bitfield.
3734    Return a pointer to the character after that string. */
3735 /*XXX this needs a buf_len check */
3736 static char *
3737 other_decode_bitfield_value(char *buf, const guint64 val, const guint64 mask, const int width)
3738 {
3739         int i;
3740         guint64 bit;
3741         char *p;
3742
3743         i = 0;
3744         p = buf;
3745         bit = G_GUINT64_CONSTANT(1) << (width - 1);
3746         for (;;) {
3747                 if (mask & bit) {
3748                         /* This bit is part of the field.  Show its value. */
3749                         if (val & bit)
3750                                 *p++ = '1';
3751                         else
3752                                 *p++ = '0';
3753                 } else {
3754                         /* This bit is not part of the field. */
3755                         *p++ = '.';
3756                 }
3757                 bit >>= 1;
3758                 i++;
3759                 if (i >= width)
3760                         break;
3761                 if (i % 4 == 0)
3762                         *p++ = ' ';
3763         }
3764         *p = '\0';
3765         return p;
3766 }
3767
3768 static char *
3769 decode_bitfield_value(char *buf, const guint64 val, const guint64 mask, const int width)
3770 {
3771         char *p;
3772
3773         p = other_decode_bitfield_value(buf, val, mask, width);
3774         p = g_stpcpy(p, " = ");
3775
3776         return p;
3777 }
3778
3779 /* Add a FT_FLOAT to a proto_tree */
3780 proto_item *
3781 proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3782                      gint length, float value)
3783 {
3784         proto_item        *pi;
3785         header_field_info *hfinfo;
3786
3787         CHECK_FOR_NULL_TREE(tree);
3788
3789         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3790
3791         DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_FLOAT);
3792
3793         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3794         proto_tree_set_float(PNODE_FINFO(pi), value);
3795
3796         return pi;
3797 }
3798
3799 proto_item *
3800 proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3801                                   gint start, gint length, float value,
3802                                   const char *format, ...)
3803 {
3804         proto_item        *pi;
3805         va_list            ap;
3806
3807         pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
3808         if (pi != tree) {
3809                 va_start(ap, format);
3810                 proto_tree_set_representation_value(pi, format, ap);
3811                 va_end(ap);
3812         }
3813
3814         return pi;
3815 }
3816
3817 proto_item *
3818 proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3819                             gint start, gint length, float value,
3820                             const char *format, ...)
3821 {
3822         proto_item        *pi;
3823         va_list            ap;
3824
3825         pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
3826         if (pi != tree) {
3827                 TRY_TO_FAKE_THIS_REPR(pi);
3828
3829                 va_start(ap, format);
3830                 proto_tree_set_representation(pi, format, ap);
3831                 va_end(ap);
3832         }
3833
3834         return pi;
3835 }
3836
3837 /* Set the FT_FLOAT value */
3838 static void
3839 proto_tree_set_float(field_info *fi, float value)
3840 {
3841         fvalue_set_floating(&fi->value, value);
3842 }
3843
3844 /* Add a FT_DOUBLE to a proto_tree */
3845 proto_item *
3846 proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3847                       gint length, double value)
3848 {
3849         proto_item        *pi;
3850         header_field_info *hfinfo;
3851
3852         CHECK_FOR_NULL_TREE(tree);
3853
3854         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3855
3856         DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_DOUBLE);
3857
3858         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3859         proto_tree_set_double(PNODE_FINFO(pi), value);
3860
3861         return pi;
3862 }
3863
3864 proto_item *
3865 proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3866                                    gint start, gint length, double value,
3867                                    const char *format, ...)
3868 {
3869         proto_item        *pi;
3870         va_list            ap;
3871
3872         pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
3873         if (pi != tree) {
3874                 va_start(ap, format);
3875                 proto_tree_set_representation_value(pi, format, ap);
3876                 va_end(ap);
3877         }
3878
3879         return pi;
3880 }
3881
3882 proto_item *
3883 proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3884                              gint start, gint length, double value,
3885                              const char *format, ...)
3886 {
3887         proto_item        *pi;
3888         va_list            ap;
3889
3890         pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
3891         if (pi != tree) {
3892                 TRY_TO_FAKE_THIS_REPR(pi);
3893
3894                 va_start(ap, format);
3895                 proto_tree_set_representation(pi, format, ap);
3896                 va_end(ap);
3897         }
3898
3899         return pi;
3900 }
3901
3902 /* Set the FT_DOUBLE value */
3903 static void
3904 proto_tree_set_double(field_info *fi, double value)
3905 {
3906         fvalue_set_floating(&fi->value, value);
3907 }
3908
3909 /* Add FT_UINT{8,16,24,32} to a proto_tree */
3910 proto_item *
3911 proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3912                     gint length, guint32 value)
3913 {
3914         proto_item        *pi = NULL;
3915         header_field_info *hfinfo;
3916
3917         CHECK_FOR_NULL_TREE(tree);
3918
3919         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3920
3921         switch (hfinfo->type) {
3922                 case FT_UINT8:
3923                 case FT_UINT16:
3924                 case FT_UINT24:
3925                 case FT_UINT32:
3926                 case FT_FRAMENUM:
3927                         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3928                         proto_tree_set_uint(PNODE_FINFO(pi), value);
3929                         break;
3930
3931                 default:
3932                         DISSECTOR_ASSERT_NOT_REACHED();
3933         }
3934
3935         return pi;
3936 }
3937
3938 proto_item *
3939 proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3940                                  gint start, gint length, guint32 value,
3941                                  const char *format, ...)
3942 {
3943         proto_item        *pi;
3944         va_list            ap;
3945
3946         pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
3947         if (pi != tree) {
3948                 va_start(ap, format);
3949                 proto_tree_set_representation_value(pi, format, ap);
3950                 va_end(ap);
3951         }
3952
3953         return pi;
3954 }
3955
3956 proto_item *
3957 proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3958                            gint start, gint length, guint32 value,
3959                            const char *format, ...)
3960 {
3961         proto_item        *pi;
3962         va_list            ap;
3963
3964         pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
3965         if (pi != tree) {
3966                 TRY_TO_FAKE_THIS_REPR(pi);
3967
3968                 va_start(ap, format);
3969                 proto_tree_set_representation(pi, format, ap);
3970                 va_end(ap);
3971         }
3972
3973         return pi;
3974 }
3975
3976 /* Set the FT_UINT{8,16,24,32} value */
3977 static void
3978 proto_tree_set_uint(field_info *fi, guint32 value)
3979 {
3980         header_field_info *hfinfo;
3981         guint32            integer;
3982
3983         hfinfo = fi->hfinfo;
3984         integer = value;
3985
3986         if (hfinfo->bitmask) {
3987                 /* Mask out irrelevant portions */
3988                 integer &= (guint32)(hfinfo->bitmask);
3989
3990                 /* Shift bits */
3991                 integer >>= hfinfo_bitshift(hfinfo);
3992         }
3993
3994         fvalue_set_uinteger(&fi->value, integer);
3995 }
3996
3997 /* Add FT_UINT{40,48,56,64} to a proto_tree */
3998 proto_item *
3999 proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4000                       gint length, guint64 value)
4001 {
4002         proto_item        *pi = NULL;
4003         header_field_info *hfinfo;
4004
4005         CHECK_FOR_NULL_TREE(tree);
4006
4007         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4008
4009         switch (hfinfo->type) {
4010                 case FT_UINT40:
4011                 case FT_UINT48:
4012                 case FT_UINT56:
4013                 case FT_UINT64:
4014                 case FT_FRAMENUM:
4015                         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4016                         proto_tree_set_uint64(PNODE_FINFO(pi), value);
4017                         break;
4018
4019                 default:
4020                         DISSECTOR_ASSERT_NOT_REACHED();
4021         }
4022
4023         return pi;
4024 }
4025
4026 proto_item *
4027 proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4028                                    gint start, gint length, guint64 value,
4029                                    const char *format, ...)
4030 {
4031         proto_item        *pi;
4032         va_list            ap;
4033
4034         pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
4035         if (pi != tree) {
4036                 va_start(ap, format);
4037                 proto_tree_set_representation_value(pi, format, ap);
4038                 va_end(ap);
4039         }
4040
4041         return pi;
4042 }
4043
4044 proto_item *
4045 proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4046                              gint start, gint length, guint64 value,
4047                              const char *format, ...)
4048 {
4049         proto_item        *pi;
4050         va_list            ap;
4051
4052         pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
4053         if (pi != tree) {
4054                 TRY_TO_FAKE_THIS_REPR(pi);
4055
4056                 va_start(ap, format);
4057                 proto_tree_set_representation(pi, format, ap);
4058                 va_end(ap);
4059         }
4060
4061         return pi;
4062 }
4063
4064 /* Set the FT_UINT{40,48,56,64} value */
4065 static void
4066 proto_tree_set_uint64(field_info *fi, guint64 value)
4067 {
4068         header_field_info *hfinfo;
4069         guint64            integer;
4070
4071         hfinfo = fi->hfinfo;
4072         integer = value;
4073
4074         if (hfinfo->bitmask) {
4075                 /* Mask out irrelevant portions */
4076                 integer &= hfinfo->bitmask;
4077
4078                 /* Shift bits */
4079                 integer >>= hfinfo_bitshift(hfinfo);
4080         }
4081
4082         fvalue_set_uinteger64(&fi->value, integer);
4083 }
4084
4085 /* Add FT_INT{8,16,24,32} to a proto_tree */
4086 proto_item *
4087 proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4088                    gint length, gint32 value)
4089 {
4090         proto_item        *pi = NULL;
4091         header_field_info *hfinfo;
4092
4093         CHECK_FOR_NULL_TREE(tree);
4094
4095         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4096
4097         switch (hfinfo->type) {
4098                 case FT_INT8:
4099                 case FT_INT16:
4100                 case FT_INT24:
4101                 case FT_INT32:
4102                         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4103                         proto_tree_set_int(PNODE_FINFO(pi), value);
4104                         break;
4105
4106                 default:
4107                         DISSECTOR_ASSERT_NOT_REACHED();
4108         }
4109
4110         return pi;
4111 }
4112
4113 proto_item *
4114 proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4115                                 gint start, gint length, gint32 value,
4116                                 const char *format, ...)
4117 {
4118         proto_item  *pi;
4119         va_list      ap;
4120
4121         pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
4122         if (pi != tree) {
4123                 va_start(ap, format);
4124                 proto_tree_set_representation_value(pi, format, ap);
4125                 va_end(ap);
4126         }
4127
4128         return pi;
4129 }
4130
4131 proto_item *
4132 proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4133                           gint start, gint length, gint32 value,
4134                           const char *format, ...)
4135 {
4136         proto_item *pi;
4137         va_list     ap;
4138
4139         pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
4140         if (pi != tree) {
4141                 TRY_TO_FAKE_THIS_REPR(pi);
4142
4143                 va_start(ap, format);
4144                 proto_tree_set_representation(pi, format, ap);
4145                 va_end(ap);
4146         }
4147
4148         return pi;
4149 }
4150
4151 /* Set the FT_INT{8,16,24,32} value */
4152 static void
4153 proto_tree_set_int(field_info *fi, gint32 value)
4154 {
4155         header_field_info *hfinfo;
4156         guint32            integer;
4157         gint               no_of_bits;
4158
4159         hfinfo = fi->hfinfo;
4160         integer = (guint32) value;
4161
4162         if (hfinfo->bitmask) {
4163                 /* Mask out irrelevant portions */
4164                 integer &= (guint32)(hfinfo->bitmask);
4165
4166                 /* Shift bits */
4167                 integer >>= hfinfo_bitshift(hfinfo);
4168
4169                 no_of_bits = ws_count_ones(hfinfo->bitmask);
4170                 integer = ws_sign_ext32(integer, no_of_bits);
4171         }
4172
4173         fvalue_set_sinteger(&fi->value, integer);
4174 }
4175
4176 /* Add FT_INT{40,48,56,64} to a proto_tree */
4177 proto_item *
4178 proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4179                      gint length, gint64 value)
4180 {
4181         proto_item        *pi = NULL;
4182         header_field_info *hfinfo;
4183
4184         CHECK_FOR_NULL_TREE(tree);
4185
4186         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4187
4188         switch (hfinfo->type) {
4189                 case FT_INT40:
4190                 case FT_INT48:
4191                 case FT_INT56:
4192                 case FT_INT64:
4193                         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4194                         proto_tree_set_int64(PNODE_FINFO(pi), value);
4195                         break;
4196
4197                 default:
4198                         DISSECTOR_ASSERT_NOT_REACHED();
4199         }
4200
4201         return pi;
4202 }
4203
4204 proto_item *
4205 proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4206                                   gint start, gint length, gint64 value,
4207                                   const char *format, ...)
4208 {
4209         proto_item        *pi;
4210         va_list            ap;
4211
4212         pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
4213         if (pi != tree) {
4214                 va_start(ap, format);
4215                 proto_tree_set_representation_value(pi, format, ap);
4216                 va_end(ap);
4217         }
4218
4219         return pi;
4220 }
4221
4222 /* Set the FT_INT{40,48,56,64} value */
4223 static void
4224 proto_tree_set_int64(field_info *fi, gint64 value)
4225 {
4226         header_field_info *hfinfo;
4227         guint64            integer;
4228         gint               no_of_bits;
4229
4230         hfinfo = fi->hfinfo;
4231         integer = value;
4232
4233         if (hfinfo->bitmask) {
4234                 /* Mask out irrelevant portions */
4235                 integer &= hfinfo->bitmask;
4236
4237                 /* Shift bits */
4238                 integer >>= hfinfo_bitshift(hfinfo);
4239
4240                 no_of_bits = ws_count_ones(hfinfo->bitmask);
4241                 integer = ws_sign_ext64(integer, no_of_bits);
4242         }
4243
4244         fvalue_set_sinteger64(&fi->value, integer);
4245 }
4246
4247 proto_item *
4248 proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4249                            gint start, gint length, gint64 value,
4250                            const char *format, ...)
4251 {
4252         proto_item        *pi;
4253         va_list            ap;
4254
4255         pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
4256         if (pi != tree) {
4257                 TRY_TO_FAKE_THIS_REPR(pi);
4258
4259                 va_start(ap, format);
4260                 proto_tree_set_representation(pi, format, ap);
4261                 va_end(ap);
4262         }
4263
4264         return pi;
4265 }
4266
4267 /* Add a FT_EUI64 to a proto_tree */
4268 proto_item *
4269 proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
4270                      gint length, const guint64 value)
4271 {
4272         proto_item        *pi;
4273         header_field_info *hfinfo;
4274
4275         CHECK_FOR_NULL_TREE(tree);
4276
4277         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4278
4279         DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_EUI64);
4280
4281         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4282         proto_tree_set_eui64(PNODE_FINFO(pi), value);
4283
4284         return pi;
4285 }
4286
4287 proto_item *
4288 proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4289                                   gint start, gint length, const guint64 value,
4290                                   const char *format, ...)
4291 {
4292         proto_item        *pi;
4293         va_list            ap;
4294
4295         pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
4296         if (pi != tree) {
4297                 va_start(ap, format);
4298                 proto_tree_set_representation_value(pi, format, ap);
4299                 va_end(ap);
4300         }
4301
4302         return pi;
4303 }
4304
4305 proto_item *
4306 proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4307                             gint start, gint length, const guint64 value,
4308                             const char *format, ...)
4309 {
4310         proto_item        *pi;
4311         va_list            ap;
4312
4313         pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
4314         if (pi != tree) {
4315                 TRY_TO_FAKE_THIS_REPR(pi);
4316
4317                 va_start(ap, format);
4318                 proto_tree_set_representation(pi, format, ap);
4319                 va_end(ap);
4320         }
4321
4322         return pi;
4323 }
4324
4325 /* Set the FT_EUI64 value */
4326 static void
4327 proto_tree_set_eui64(field_info *fi, const guint64 value)
4328 {
4329         fvalue_set_uinteger64(&fi->value, value);
4330 }
4331 static void
4332 proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, gint start, const guint encoding)
4333 {
4334         if (encoding)
4335         {
4336                 proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
4337         } else {
4338                 proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
4339         }
4340 }
4341
4342 /* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
4343 static proto_item *
4344 proto_tree_add_node(proto_tree *tree, field_info *fi)
4345 {
4346         proto_node *pnode, *tnode, *sibling;
4347         field_info *tfi;
4348         int depth = 1;
4349
4350         /*
4351          * Restrict our depth. proto_tree_traverse_pre_order and
4352          * proto_tree_traverse_post_order (and possibly others) are recursive
4353          * so we need to be mindful of our stack size.
4354          */
4355         if (tree->first_child == NULL) {
4356                 for (tnode = tree; tnode != NULL; tnode = tnode->parent) {
4357                         depth++;
4358                         if (G_UNLIKELY(depth > MAX_TREE_LEVELS)) {
4359                                 THROW_MESSAGE(DissectorError, wmem_strdup_printf(wmem_packet_scope(),
4360                                                      "Maximum tree depth %d exceeded for \"%s\" - \"%s\" (%s:%u)",
4361                                                      MAX_TREE_LEVELS,
4362                                                      fi->hfinfo->name, fi->hfinfo->abbrev, G_STRFUNC, __LINE__));
4363                         }
4364                 }
4365         }
4366
4367         /*
4368          * Make sure "tree" is ready to have subtrees under it, by
4369          * checking whether it's been given an ett_ value.
4370          *
4371          * "PNODE_FINFO(tnode)" may be null; that's the case for the root
4372          * node of the protocol tree.  That node is not displayed,
4373          * so it doesn't need an ett_ value to remember whether it
4374          * was expanded.
4375          */
4376         tnode = tree;
4377         tfi = PNODE_FINFO(tnode);
4378         if (tfi != NULL && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
4379                 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
4380                                      "\"%s\" - \"%s\" tfi->tree_type: %u invalid (%s:%u)",
4381                                      fi->hfinfo->name, fi->hfinfo->abbrev, tfi->tree_type, __FILE__, __LINE__));
4382                 /* XXX - is it safe to continue here? */
4383         }
4384
4385         pnode = wmem_new(PNODE_POOL(tree), proto_node);
4386         PROTO_NODE_INIT(pnode);
4387         pnode->parent = tnode;
4388         PNODE_FINFO(pnode) = fi;
4389         pnode->tree_data = PTREE_DATA(tree);
4390
4391         if (tnode->last_child != NULL) {
4392                 sibling = tnode->last_child;
4393                 DISSECTOR_ASSERT(sibling->next == NULL);
4394                 sibling->next = pnode;
4395         } else
4396                 tnode->first_child = pnode;
4397         tnode->last_child = pnode;
4398
4399         tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
4400
4401         return (proto_item *)pnode;
4402 }
4403
4404
4405 /* Generic way to allocate field_info and add to proto_tree.
4406  * Sets *pfi to address of newly-allocated field_info struct */
4407 static proto_item *
4408 proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, gint start,
4409                   gint *length)
4410 {
4411         proto_item *pi;
4412         field_info *fi;
4413         gint            item_length;
4414
4415         get_hfi_length(hfinfo, tvb, start, length, &item_length);
4416         fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4417         pi = proto_tree_add_node(tree, fi);
4418
4419         return pi;
4420 }
4421
4422
4423 static void
4424 get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start, gint *length,
4425                    gint *item_length)
4426 {
4427         gint length_remaining;
4428
4429         /*
4430          * We only allow a null tvbuff if the item has a zero length,
4431          * i.e. if there's no data backing it.
4432          */
4433         DISSECTOR_ASSERT(tvb != NULL || *length == 0);
4434
4435         /*
4436          * XXX - in some protocols, there are 32-bit unsigned length
4437          * fields, so lengths in protocol tree and tvbuff routines
4438          * should really be unsigned.  We should have, for those
4439          * field types for which "to the end of the tvbuff" makes sense,
4440          * additional routines that take no length argument and
4441          * add fields that run to the end of the tvbuff.
4442          */
4443         if (*length == -1) {
4444                 /*
4445                  * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING, and
4446                  * FT_STRINGZPAD fields, a length of -1 means "set the
4447                  * length to what remains in the tvbuff".
4448                  *
4449                  * The assumption is either that
4450                  *
4451                  *      1) the length of the item can only be determined
4452                  *         by dissection (typically true of items with
4453                  *         subitems, which are probably FT_NONE or
4454                  *         FT_PROTOCOL)
4455                  *
4456                  * or
4457                  *
4458                  *      2) if the tvbuff is "short" (either due to a short
4459                  *         snapshot length or due to lack of reassembly of
4460                  *         fragments/segments/whatever), we want to display
4461                  *         what's available in the field (probably FT_BYTES
4462                  *         or FT_STRING) and then throw an exception later
4463                  *
4464                  * or
4465                  *
4466                  *      3) the field is defined to be "what's left in the
4467                  *         packet"
4468                  *
4469                  * so we set the length to what remains in the tvbuff so
4470                  * that, if we throw an exception while dissecting, it
4471                  * has what is probably the right value.
4472                  *
4473                  * For FT_STRINGZ, it means "the string is null-terminated,
4474                  * not null-padded; set the length to the actual length
4475                  * of the string", and if the tvbuff if short, we just
4476                  * throw an exception.
4477                  *
4478                  * It's not valid for any other type of field.  For those
4479                  * fields, we treat -1 the same way we treat other
4480                  * negative values - we assume the length is a Really
4481                  * Big Positive Number, and throw a ReportedBoundsError
4482                  * exception, under the assumption that the Really Big
4483                  * Length would run past the end of the packet.
4484                  */
4485                 switch (hfinfo->type) {
4486
4487                 case FT_PROTOCOL:
4488                 case FT_NONE:
4489                 case FT_BYTES:
4490                 case FT_STRING:
4491                 case FT_STRINGZPAD:
4492                         /*
4493                          * We allow FT_PROTOCOLs to be zero-length -
4494                          * for example, an ONC RPC NULL procedure has
4495                          * neither arguments nor reply, so the
4496                          * payload for that protocol is empty.
4497                          *
4498                          * We also allow the others to be zero-length -
4499                          * because that's the way the code has been for a
4500                          * long, long time.
4501                          *
4502                          * However, we want to ensure that the start
4503                          * offset is not *past* the byte past the end
4504                          * of the tvbuff: we throw an exception in that
4505                          * case.
4506                          */
4507                         *length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
4508                         DISSECTOR_ASSERT(*length >= 0);
4509                         break;
4510
4511                 case FT_STRINGZ:
4512                         /*
4513                          * Leave the length as -1, so our caller knows
4514                          * it was -1.
4515                          */
4516                         break;
4517
4518                 default:
4519                         THROW(ReportedBoundsError);
4520                         DISSECTOR_ASSERT_NOT_REACHED();
4521                 }
4522                 *item_length = *length;
4523         } else {
4524                 *item_length = *length;
4525                 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
4526                         /*
4527                          * These types are for interior nodes of the
4528                          * tree, and don't have data associated with
4529                          * them; if the length is negative (XXX - see
4530                          * above) or goes past the end of the tvbuff,
4531                          * cut it short at the end of the tvbuff.
4532                          * That way, if this field is selected in
4533                          * Wireshark, we don't highlight stuff past
4534                          * the end of the data.
4535                          */
4536                         /* XXX - what to do, if we don't have a tvb? */
4537                         if (tvb) {
4538                                 length_remaining = tvb_captured_length_remaining(tvb, start);
4539                                 if (*item_length < 0 ||
4540                                         (*item_length > 0 &&
4541                                           (length_remaining < *item_length)))
4542                                         *item_length = length_remaining;
4543                         }
4544                 }
4545                 if (*item_length < 0) {
4546                         THROW(ReportedBoundsError);
4547                 }
4548         }
4549 }
4550
4551 static gint
4552 get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start,
4553                 gint length, guint item_length, const gint encoding)
4554 {
4555         guint32 n;
4556
4557         /*
4558          * We need to get the correct item length here.
4559          * That's normally done by proto_tree_new_item(),
4560          * but we won't be calling it.
4561          */
4562         switch (hfinfo->type) {
4563
4564         case FT_NONE:
4565         case FT_PROTOCOL:
4566         case FT_BYTES:
4567                 /*
4568                  * The length is the specified length.
4569                  */
4570                 break;
4571
4572         case FT_UINT_BYTES:
4573                 /*
4574                  * Map all non-zero values to little-endian for
4575                  * backwards compatibility.
4576                  */
4577                 n = get_uint_value(NULL, tvb, start, length,
4578                     encoding ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN);
4579                 item_length += n;
4580                 break;
4581
4582         case FT_BOOLEAN:
4583         /* XXX - make these just FT_UINT? */
4584         case FT_UINT8:
4585         case FT_UINT16:
4586         case FT_UINT24:
4587         case FT_UINT32:
4588         case FT_UINT40:
4589         case FT_UINT48:
4590         case FT_UINT56:
4591         case FT_UINT64:
4592         /* XXX - make these just FT_INT? */
4593         case FT_INT8:
4594         case FT_INT16:
4595         case FT_INT24:
4596         case FT_INT32:
4597         case FT_INT40:
4598         case FT_INT48:
4599         case FT_INT56:
4600         case FT_INT64:
4601         case FT_IPv4:
4602         case FT_IPXNET:
4603         case FT_IPv6:
4604         case FT_FCWWN:
4605         case FT_AX25:
4606         case FT_VINES:
4607         case FT_ETHER:
4608         case FT_EUI64:
4609         case FT_GUID:
4610         case FT_OID:
4611         case FT_REL_OID:
4612         case FT_SYSTEM_ID:
4613         case FT_FLOAT:
4614         case FT_DOUBLE:
4615         case FT_STRING:
4616                 /*
4617                  * The length is the specified length.
4618                  */
4619                 break;
4620
4621         case FT_STRINGZ:
4622                 if (length < -1) {
4623                         report_type_length_mismatch(NULL, "a string", length, TRUE);
4624                 }
4625                 if (length == -1) {
4626                         /* This can throw an exception */
4627                         /* XXX - do this without fetching the string? */
4628                         tvb_get_stringz_enc(wmem_packet_scope(), tvb, start, &length, encoding);
4629                 }
4630                 item_length = length;
4631                 break;
4632
4633         case FT_UINT_STRING:
4634                 n = get_uint_value(NULL, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK);
4635                 item_length += n;
4636                 break;
4637
4638         case FT_STRINGZPAD:
4639         case FT_ABSOLUTE_TIME:
4640         case FT_RELATIVE_TIME:
4641         case FT_IEEE_11073_SFLOAT:
4642         case FT_IEEE_11073_FLOAT:
4643                 /*
4644                  * The length is the specified length.
4645                  */
4646                 break;
4647
4648         default:
4649                 g_error("hfinfo->type %d (%s) not handled\n",
4650                                 hfinfo->type,
4651                                 ftype_name(hfinfo->type));
4652                 DISSECTOR_ASSERT_NOT_REACHED();
4653                 break;
4654         }
4655         return item_length;
4656 }
4657
4658 static field_info *
4659 new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
4660                const gint start, const gint item_length)
4661 {
4662         field_info *fi;
4663
4664         FIELD_INFO_NEW(PNODE_POOL(tree), fi);
4665
4666         fi->hfinfo     = hfinfo;
4667         fi->start      = start;
4668         fi->start     += (tvb)?tvb_raw_offset(tvb):0;
4669         fi->length     = item_length;
4670         fi->tree_type  = -1;
4671         fi->flags      = 0;
4672         if (!PTREE_DATA(tree)->visible)
4673                 FI_SET_FLAG(fi, FI_HIDDEN);
4674         fvalue_init(&fi->value, fi->hfinfo->type);
4675         fi->rep        = NULL;
4676
4677         /* add the data source tvbuff */
4678         fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL;
4679
4680         fi->appendix_start  = 0;
4681         fi->appendix_length = 0;
4682
4683         return fi;
4684 }
4685
4686 /* If the protocol tree is to be visible, set the representation of a
4687    proto_tree entry with the name of the field for the item and with
4688    the value formatted with the supplied printf-style format and
4689    argument list. */
4690 static void
4691 proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
4692 {
4693         g_assert(pi);
4694
4695         /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
4696          * items string representation */
4697         if (PTREE_DATA(pi)->visible && !PROTO_ITEM_IS_HIDDEN(pi)) {
4698                 int               ret = 0;
4699                 field_info        *fi = PITEM_FINFO(pi);
4700                 header_field_info *hf;
4701
4702                 DISSECTOR_ASSERT(fi);
4703
4704                 hf = fi->hfinfo;
4705
4706                 ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
4707                 if (hf->bitmask && (hf->type == FT_BOOLEAN || IS_FT_UINT(hf->type))) {
4708                         guint64 val;
4709                         char *p;
4710
4711                         if (IS_FT_UINT(hf->type))
4712                                 val = fvalue_get_uinteger(&fi->value);
4713                         else
4714                                 val = fvalue_get_uinteger64(&fi->value);
4715
4716                         val <<= hfinfo_bitshift(hf);
4717
4718                         p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
4719                         ret = (int) (p - fi->rep->representation);
4720                 }
4721
4722                 /* put in the hf name */
4723                 ret += g_snprintf(fi->rep->representation + ret, ITEM_LABEL_LENGTH - ret, "%s: ", hf->name);
4724
4725                 /* If possible, Put in the value of the string */
4726                 if (ret < ITEM_LABEL_LENGTH) {
4727                         ret += g_vsnprintf(fi->rep->representation + ret,
4728                                           ITEM_LABEL_LENGTH - ret, format, ap);
4729                 }
4730                 if (ret >= ITEM_LABEL_LENGTH) {
4731                         /* Uh oh, we don't have enough room.  Tell the user
4732                          * that the field is truncated.
4733                          */
4734                         LABEL_MARK_TRUNCATED_START(fi->rep->representation);
4735                 }
4736         }
4737 }
4738
4739 /* If the protocol tree is to be visible, set the representation of a
4740    proto_tree entry with the representation formatted with the supplied
4741    printf-style format and argument list. */
4742 static void
4743 proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
4744 {
4745         int         ret;        /*tmp return value */
4746         field_info *fi = PITEM_FINFO(pi);
4747
4748         DISSECTOR_ASSERT(fi);
4749
4750         if (!PROTO_ITEM_IS_HIDDEN(pi)) {
4751                 ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
4752                 ret = g_vsnprintf(fi->rep->representation, ITEM_LABEL_LENGTH,
4753                                   format, ap);
4754                 if (ret >= ITEM_LABEL_LENGTH) {
4755                         /* Uh oh, we don't have enough room.  Tell the user
4756                          * that the field is truncated.
4757                          */
4758                         LABEL_MARK_TRUNCATED_START(fi->rep->representation);
4759                 }
4760         }
4761 }
4762
4763 static const char *
4764 hfinfo_format_text(const header_field_info *hfinfo, const guchar *string)
4765 {
4766         switch (hfinfo->display) {
4767                 case STR_ASCII:
4768                         return format_text(string, strlen(string));
4769 /*
4770                 case STR_ASCII_WSP
4771                         return format_text_wsp(string, strlen(string));
4772  */
4773                 case STR_UNICODE:
4774                         /* XXX, format_unicode_text() */
4775                         return string;
4776         }
4777
4778         return format_text(string, strlen(string));
4779 }
4780
4781 static int
4782 protoo_strlcpy(gchar *dest, const gchar *src, gsize dest_size)
4783 {
4784         gsize res = g_strlcpy(dest, src, dest_size);
4785
4786         if (res > dest_size)
4787                 res = dest_size;
4788         return (int) res;
4789 }
4790
4791 static header_field_info *
4792 hfinfo_same_name_get_prev(const header_field_info *hfinfo)
4793 {
4794         header_field_info *dup_hfinfo;
4795
4796         if (hfinfo->same_name_prev_id == -1)
4797                 return NULL;
4798         PROTO_REGISTRAR_GET_NTH(hfinfo->same_name_prev_id, dup_hfinfo);
4799         return dup_hfinfo;
4800 }
4801
4802 static void
4803 hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
4804 {
4805         g_free(last_field_name);
4806         last_field_name = NULL;
4807
4808         if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
4809                 /* No hfinfo with the same name */
4810                 g_hash_table_steal(gpa_name_map, hfinfo->abbrev);
4811                 return;
4812         }
4813
4814         if (hfinfo->same_name_next) {
4815                 hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
4816         }
4817
4818         if (hfinfo->same_name_prev_id != -1) {
4819                 header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
4820                 same_name_prev->same_name_next = hfinfo->same_name_next;
4821                 if (!hfinfo->same_name_next) {
4822                         /* It's always the latest added hfinfo which is stored in gpa_name_map */
4823                         g_hash_table_insert(gpa_name_map, (gpointer) (same_name_prev->abbrev), same_name_prev);
4824                 }
4825         }
4826 }
4827
4828 /* -------------------------- */
4829 const gchar *
4830 proto_custom_set(proto_tree* tree, GSList *field_ids, gint occurrence,
4831                  gchar *result, gchar *expr, const int size)
4832 {
4833         guint32             number;
4834         guint64             number64;
4835         guint8             *bytes;
4836         ipv4_addr_and_mask *ipv4;
4837         struct e_in6_addr  *ipv6;
4838         address             addr;
4839         guint32             n_addr; /* network-order IPv4 address */
4840
4841         const true_false_string  *tfstring;
4842
4843         int                 len, prev_len = 0, last, i, offset_r = 0, offset_e = 0;
4844         GPtrArray          *finfos;
4845         field_info         *finfo         = NULL;
4846         header_field_info*  hfinfo;
4847         const gchar        *abbrev        = NULL;
4848
4849         const char *hf_str_val;
4850         char number_buf[48];
4851         const char *number_out;
4852         char *tmpbuf, *str;
4853         int *field_idx;
4854         int field_id;
4855         int ii = 0;
4856
4857         g_assert(field_ids != NULL);
4858         while ((field_idx = (int *) g_slist_nth_data(field_ids, ii++))) {
4859                 field_id = *field_idx;
4860                 PROTO_REGISTRAR_GET_NTH((guint)field_id, hfinfo);
4861
4862                 /* do we need to rewind ? */
4863                 if (!hfinfo)
4864                         return "";
4865
4866                 if (occurrence < 0) {
4867                         /* Search other direction */
4868                         while (hfinfo->same_name_prev_id != -1) {
4869                                 PROTO_REGISTRAR_GET_NTH(hfinfo->same_name_prev_id, hfinfo);
4870                         }
4871                 }
4872
4873                 while (hfinfo) {
4874                         finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
4875
4876                         if (!finfos || !(len = g_ptr_array_len(finfos))) {
4877                                 if (occurrence < 0) {
4878                                         hfinfo = hfinfo->same_name_next;
4879                                 } else {
4880                                         hfinfo = hfinfo_same_name_get_prev(hfinfo);
4881                                 }
4882                                 continue;
4883                         }
4884
4885                         /* Are there enough occurrences of the field? */
4886                         if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
4887                                 if (occurrence < 0) {
4888                                         hfinfo = hfinfo->same_name_next;
4889                                 } else {
4890                                         hfinfo = hfinfo_same_name_get_prev(hfinfo);
4891                                 }
4892                                 prev_len += len;
4893                                 continue;
4894                         }
4895
4896                         /* Calculate single index or set outer bounderies */
4897                         if (occurrence < 0) {
4898                                 i = occurrence + len + prev_len;
4899                                 last = i;
4900                         } else if (occurrence > 0) {
4901                                 i = occurrence - 1 - prev_len;
4902                                 last = i;
4903                         } else {
4904                                 i = 0;
4905                                 last = len - 1;
4906                         }
4907
4908                         prev_len += len; /* Count handled occurrences */
4909
4910                         while (i <= last) {
4911                                 finfo = (field_info *)g_ptr_array_index(finfos, i);
4912
4913                                 if (offset_r && (offset_r < (size - 2)))
4914                                         result[offset_r++] = ',';
4915
4916                                 if (offset_e && (offset_e < (size - 2)))
4917                                         expr[offset_e++] = ',';
4918
4919                                 switch (hfinfo->type) {
4920
4921                                         case FT_NONE: /* Nothing to add */
4922                                                 if (offset_r == 0) {
4923                                                         result[0] = '\0';
4924                                                 } else if (result[offset_r-1] == ',') {
4925                                                         result[offset_r-1] = '\0';
4926                                                 }
4927                                                 break;
4928
4929                                         case FT_PROTOCOL:
4930                                                 /* prevent multiple "yes" entries by setting result directly */
4931                                                 g_strlcpy(result, "Yes", size);
4932                                                 break;
4933
4934                                         case FT_UINT_BYTES:
4935                                         case FT_BYTES:
4936                                                 bytes = (guint8 *)fvalue_get(&finfo->value);
4937                                                 if (bytes) {
4938                                                         switch(hfinfo->display)
4939                                                         {
4940                                                         case SEP_DOT:
4941                                                                 str = bytestring_to_str(NULL, bytes, fvalue_length(&finfo->value), '.');
4942                                                                 break;
4943                                                         case SEP_DASH:
4944                                                                 str = bytestring_to_str(NULL, bytes, fvalue_length(&finfo->value), '-');
4945                                                                 break;
4946                                                         case SEP_COLON:
4947                                                                 str = bytestring_to_str(NULL, bytes, fvalue_length(&finfo->value), ':');
4948                                                                 break;
4949                                                         case SEP_SPACE:
4950                                                                 str = bytestring_to_str(NULL, bytes, fvalue_length(&finfo->value), ' ');
4951                                                                 break;
4952                                                         case BASE_NONE:
4953                                                         default:
4954                                                                 if (prefs.display_byte_fields_with_spaces)
4955                                                                 {
4956                                                                         str = bytestring_to_str(NULL, bytes, fvalue_length(&finfo->value), ' ');
4957                                                                 }
4958                                                                 else
4959                                                                 {
4960                                                                         str = bytes_to_str(NULL, bytes, fvalue_length(&finfo->value));
4961                                                                 }
4962                                                                 break;
4963                                                         }
4964                                                         offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
4965                                                         wmem_free(NULL, str);
4966                                                 }
4967                                                 else {
4968                                                         if (hfinfo->display & BASE_ALLOW_ZERO) {
4969                                                                 offset_r += protoo_strlcpy(result+offset_r, "<none>", size-offset_r);
4970                                                         } else {
4971                                                                 offset_r += protoo_strlcpy(result+offset_r, "<MISSING>", size-offset_r);
4972                                                         }
4973                                                 }
4974                                                 break;
4975
4976                                         case FT_ABSOLUTE_TIME:
4977                                                 tmpbuf = abs_time_to_str(NULL, (const nstime_t *)fvalue_get(&finfo->value), (absolute_time_display_e)hfinfo->display, TRUE);
4978                                                 offset_r += protoo_strlcpy(result+offset_r,
4979                                                                 tmpbuf,
4980                                                                 size-offset_r);
4981                                                 wmem_free(NULL, tmpbuf);
4982                                                 break;
4983
4984                                         case FT_RELATIVE_TIME:
4985                                                 tmpbuf = rel_time_to_secs_str(NULL, (const nstime_t *)fvalue_get(&finfo->value));
4986                                                 offset_r += protoo_strlcpy(result+offset_r,
4987                                                                 tmpbuf,
4988                                                                 size-offset_r);
4989                                                 wmem_free(NULL, tmpbuf);
4990                                                 break;
4991
4992                                         case FT_BOOLEAN:
4993                                                 number64 = fvalue_get_uinteger64(&finfo->value);
4994                                                 tfstring = (const true_false_string *)&tfs_true_false;
4995                                                 if (hfinfo->strings) {
4996                                                         tfstring = (const struct true_false_string*) hfinfo->strings;
4997                                                 }
4998                                                 offset_r += protoo_strlcpy(result+offset_r,
4999                                                                 number64 ?
5000                                                                 tfstring->true_string :
5001                                                                 tfstring->false_string, size-offset_r);
5002
5003                                                 offset_e += protoo_strlcpy(expr+offset_e,
5004                                                                 number64 ? "1" : "0", size-offset_e);
5005                                                 break;
5006
5007                                                 /* XXX - make these just FT_NUMBER? */
5008                                         case FT_INT8:
5009                                         case FT_INT16:
5010                                         case FT_INT24:
5011                                         case FT_INT32:
5012                                         case FT_UINT8:
5013                                         case FT_UINT16:
5014                                         case FT_UINT24:
5015                                         case FT_UINT32:
5016                                         case FT_FRAMENUM:
5017                                                 hf_str_val = NULL;
5018                                                 number = IS_FT_INT(hfinfo->type) ?
5019                                                         (guint32) fvalue_get_sinteger(&finfo->value) :
5020                                                         fvalue_get_uinteger(&finfo->value);
5021
5022                                                 if ((hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_CUSTOM) {
5023                                                         gchar tmp[ITEM_LABEL_LENGTH];
5024                                                         custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
5025
5026                                                         DISSECTOR_ASSERT(fmtfunc);
5027                                                         fmtfunc(tmp, number);
5028
5029                                                         offset_r += protoo_strlcpy(result+offset_r, tmp, size-offset_r);
5030
5031                                                 } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
5032                                                         number_out = hf_str_val = hf_try_val_to_str(number, hfinfo);
5033
5034                                                         if (!number_out)
5035                                                                 number_out = hfinfo_number_value_format_display(hfinfo, BASE_DEC, number_buf, number);
5036
5037                                                         offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
5038
5039                                                 } else {
5040                                                         number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
5041
5042                                                         offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
5043                                                 }
5044
5045                                                 if (hf_str_val && (hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_NONE) {
5046                                                         g_snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
5047                                                 } else {
5048                                                         number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
5049
5050                                                         g_strlcpy(expr+offset_e, number_out, size-offset_e);
5051                                                 }
5052
5053                                                 offset_e = (int)strlen(expr);
5054                                                 break;
5055
5056                                         case FT_INT40:
5057                                         case FT_INT48:
5058                                         case FT_INT56:
5059                                         case FT_INT64:
5060                                         case FT_UINT40:
5061                                         case FT_UINT48:
5062                                         case FT_UINT56:
5063                                         case FT_UINT64:
5064                                                 hf_str_val = NULL;
5065                                                 number64 = IS_FT_INT(hfinfo->type) ?
5066                                                         (guint64) fvalue_get_sinteger64(&finfo->value) :
5067                                                         fvalue_get_uinteger64(&finfo->value);
5068
5069                                                 if ((hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_CUSTOM) {
5070                                                         gchar tmp[ITEM_LABEL_LENGTH];
5071                                                         custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
5072
5073                                                         DISSECTOR_ASSERT(fmtfunc64);
5074                                                         fmtfunc64(tmp, number64);
5075                                                         offset_r += protoo_strlcpy(result+offset_r, tmp, size-offset_r);
5076                                                 } else if (hfinfo->strings) {
5077                                                         number_out = hf_str_val = hf_try_val64_to_str(number64, hfinfo);
5078
5079                                                         if (!number_out)
5080                                                                 number_out = hfinfo_number_value_format_display64(hfinfo, BASE_DEC, number_buf, number64);
5081
5082                                                         offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
5083
5084                                                 } else {
5085                                                         number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
5086
5087                                                         offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
5088                                                 }
5089
5090                                                 if (hf_str_val && (hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_NONE) {
5091                                                         g_snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
5092                                                 } else {
5093                                                         number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
5094
5095                                                         g_strlcpy(expr+offset_e, number_out, size-offset_e);
5096                                                 }
5097
5098                                                 offset_e = (int)strlen(expr);
5099                                                 break;
5100
5101                                         case FT_EUI64:
5102                                                 str = eui64_to_str(NULL, fvalue_get_uinteger64(&finfo->value));
5103                                                 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
5104                                                 wmem_free(NULL, str);
5105                                                 break;
5106
5107                                         case FT_IPv4:
5108                                                 ipv4 = (ipv4_addr_and_mask *)fvalue_get(&finfo->value);
5109                                                 n_addr = ipv4_get_net_order_addr(ipv4);
5110                                                 set_address (&addr, AT_IPv4, 4, &n_addr);
5111                                                 address_to_str_buf(&addr, result+offset_r, size-offset_r);
5112                                                 offset_r = (int)strlen(result);
5113                                                 break;
5114
5115                                         case FT_IPv6:
5116                                                 ipv6 = (struct e_in6_addr *)fvalue_get(&finfo->value);
5117                                                 set_address (&addr, AT_IPv6, sizeof(struct e_in6_addr), ipv6);
5118                                                 address_to_str_buf(&addr, result+offset_r, size-offset_r);
5119                                                 offset_r = (int)strlen(result);
5120                                                 break;
5121
5122                                         case FT_FCWWN:
5123                                                 set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN, fvalue_get(&finfo->value));
5124                                                 address_to_str_buf(&addr, result+offset_r, size-offset_r);
5125                                                 offset_r = (int)strlen(result);
5126                                                 break;
5127
5128                                         case FT_ETHER:
5129                                                 set_address (&addr, AT_ETHER, FT_ETHER_LEN, fvalue_get(&finfo->value));
5130                                                 address_to_str_buf(&addr, result+offset_r, size-offset_r);
5131                                                 offset_r = (int)strlen(result);
5132                                                 break;
5133
5134                                         case FT_GUID:
5135                                                 str = guid_to_str(NULL, (e_guid_t *)fvalue_get(&finfo->value));
5136                                                 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
5137                                                 wmem_free(NULL, str);
5138                                                 break;
5139
5140                                         case FT_REL_OID:
5141                                                 bytes = (guint8 *)fvalue_get(&finfo->value);
5142                                                 str = rel_oid_resolved_from_encoded(NULL, bytes, fvalue_length(&finfo->value));
5143                                                 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
5144                                                 wmem_free(NULL, str);
5145
5146                                                 str = rel_oid_encoded2string(NULL, bytes, fvalue_length(&finfo->value));
5147                                                 offset_e += protoo_strlcpy(expr+offset_e, str, size-offset_e);
5148                                                 wmem_free(NULL, str);
5149                                                 break;
5150
5151                                         case FT_OID:
5152                                                 bytes = (guint8 *)fvalue_get(&finfo->value);
5153                                                 str = oid_resolved_from_encoded(NULL, bytes, fvalue_length(&finfo->value));
5154                                                 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
5155                                                 wmem_free(NULL, str);
5156
5157                                                 str = oid_encoded2string(NULL, bytes, fvalue_length(&finfo->value));
5158                                                 offset_e += protoo_strlcpy(expr+offset_e, str, size-offset_e);
5159                                                 wmem_free(NULL, str);
5160                                                 break;
5161
5162                                         case FT_SYSTEM_ID:
5163                                                 bytes = (guint8 *)fvalue_get(&finfo->value);
5164                                                 str = print_system_id(NULL, bytes, fvalue_length(&finfo->value));
5165                                                 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
5166                                                 offset_e += protoo_strlcpy(expr+offset_e, str, size-offset_e);
5167                                                 wmem_free(NULL, str);
5168                                                 break;
5169
5170                                         case FT_FLOAT:
5171                                                 g_snprintf(result+offset_r, size-offset_r,
5172                                                                 "%." G_STRINGIFY(FLT_DIG) "g", fvalue_get_floating(&finfo->value));
5173                                                 offset_r = (int)strlen(result);
5174                                                 break;
5175
5176                                         case FT_DOUBLE:
5177                                                 g_snprintf(result+offset_r, size-offset_r,
5178                                                                 "%." G_STRINGIFY(DBL_DIG) "g", fvalue_get_floating(&finfo->value));
5179                                                 offset_r = (int)strlen(result);
5180                                                 break;
5181
5182                                         case FT_STRING:
5183                                         case FT_STRINGZ:
5184                                         case FT_UINT_STRING:
5185                                         case FT_STRINGZPAD:
5186                                                 bytes = (guint8 *)fvalue_get(&finfo->value);
5187                                                 offset_r += protoo_strlcpy(result+offset_r,
5188                                                                 hfinfo_format_text(hfinfo, bytes),
5189                                                                 size-offset_r);
5190                                                 break;
5191
5192                                         case FT_IEEE_11073_SFLOAT:
5193                                                 str = fvalue_to_string_repr(NULL, &finfo->value, FTREPR_DISPLAY, hfinfo->display);
5194                                                 g_snprintf(result+offset_r, size-offset_r,
5195                                                                                 "%s: %s",
5196                                                                                 hfinfo->name, str);
5197                                                 wmem_free(NULL, str);
5198                                                 offset_r = (int)strlen(result);
5199                                                 break;
5200
5201                                         case FT_IEEE_11073_FLOAT:
5202                                                 str = fvalue_to_string_repr(NULL, &finfo->value, FTREPR_DISPLAY, hfinfo->display);
5203                                                 g_snprintf(result+offset_r, size-offset_r,
5204                                                                                 "%s: %s",
5205                                                                                 hfinfo->name, str);
5206                                                 offset_r = (int)strlen(result);
5207                                                 wmem_free(NULL, str);
5208                                                 break;
5209
5210                                         case FT_IPXNET: /*XXX really No column custom ?*/
5211                                         case FT_PCRE:
5212                                         default:
5213                                                 g_error("hfinfo->type %d (%s) not handled\n",
5214                                                                 hfinfo->type,
5215                                                                 ftype_name(hfinfo->type));
5216                                                 DISSECTOR_ASSERT_NOT_REACHED();
5217                                                 break;
5218                                 }
5219                                 i++;
5220                         }
5221
5222                         switch (hfinfo->type) {
5223
5224                                 case FT_BOOLEAN:
5225                                 case FT_UINT8:
5226                                 case FT_UINT16:
5227                                 case FT_UINT24:
5228                                 case FT_UINT32:
5229                                 case FT_UINT40:
5230                                 case FT_UINT48:
5231                                 case FT_UINT56:
5232                                 case FT_UINT64:
5233                                 case FT_FRAMENUM:
5234                                 case FT_INT8:
5235                                 case FT_INT16:
5236                                 case FT_INT24:
5237                                 case FT_INT32:
5238                                 case FT_INT40:
5239                                 case FT_INT48:
5240                                 case FT_INT56:
5241                                 case FT_INT64:
5242                                 case FT_OID:
5243                                 case FT_REL_OID:
5244                                 case FT_SYSTEM_ID:
5245                                         /* for these types, "expr" is filled in the loop above */
5246                                         break;
5247
5248                                 default:
5249                                         /* for all others, just copy "result" to "expr" */
5250                                         g_strlcpy(expr, result, size);
5251                                         break;
5252                         }
5253
5254                         if (!abbrev) {
5255                                 /* Store abbrev for return value */
5256                                 abbrev = hfinfo->abbrev;
5257                         }
5258
5259                         if (occurrence == 0) {
5260                                 /* Fetch next hfinfo with same name (abbrev) */
5261                                 hfinfo = hfinfo_same_name_get_prev(hfinfo);
5262                         } else {
5263                                 hfinfo = NULL;
5264                         }
5265                 }
5266         }
5267
5268         return abbrev ? abbrev : "";
5269 }
5270
5271
5272 /* Set text of proto_item after having already been created. */
5273 void
5274 proto_item_set_text(proto_item *pi, const char *format, ...)
5275 {
5276         field_info *fi = NULL;
5277         va_list     ap;
5278
5279         TRY_TO_FAKE_THIS_REPR_VOID(pi);
5280
5281         fi = PITEM_FINFO(pi);
5282         if (fi == NULL)
5283                 return;
5284
5285         if (fi->rep) {
5286                 ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep);
5287                 fi->rep = NULL;
5288         }
5289
5290         va_start(ap, format);
5291         proto_tree_set_representation(pi, format, ap);
5292         va_end(ap);
5293 }
5294
5295 /* Append to text of proto_item after having already been created. */
5296 void
5297 proto_item_append_text(proto_item *pi, const char *format, ...)
5298 {
5299         field_info *fi = NULL;
5300         size_t      curlen;
5301         va_list     ap;
5302
5303         TRY_TO_FAKE_THIS_REPR_VOID(pi);
5304
5305         fi = PITEM_FINFO(pi);
5306         if (fi == NULL) {
5307                 return;
5308         }
5309
5310         if (!PROTO_ITEM_IS_HIDDEN(pi)) {
5311                 /*
5312                  * If we don't already have a representation,
5313                  * generate the default representation.
5314                  */
5315                 if (fi->rep == NULL) {
5316                         ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
5317                         proto_item_fill_label(fi, fi->rep->representation);
5318                 }
5319
5320                 curlen = strlen(fi->rep->representation);
5321                 if (ITEM_LABEL_LENGTH > curlen) {
5322                         va_start(ap, format);
5323                         g_vsnprintf(fi->rep->representation + curlen,
5324                                 ITEM_LABEL_LENGTH - (gulong) curlen, format, ap);
5325                         va_end(ap);
5326                 }
5327         }
5328 }
5329
5330 /* Prepend to text of proto_item after having already been created. */
5331 void
5332 proto_item_prepend_text(proto_item *pi, const char *format, ...)
5333 {
5334         field_info *fi = NULL;
5335         char        representation[ITEM_LABEL_LENGTH];
5336         va_list     ap;
5337
5338         TRY_TO_FAKE_THIS_REPR_VOID(pi);
5339
5340         fi = PITEM_FINFO(pi);
5341         if (fi == NULL) {
5342                 return;
5343         }
5344
5345         if (!PROTO_ITEM_IS_HIDDEN(pi)) {
5346                 /*
5347                  * If we don't already have a representation,
5348                  * generate the default representation.
5349                  */
5350                 if (fi->rep == NULL) {
5351                         ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
5352                         proto_item_fill_label(fi, representation);
5353                 } else
5354                         g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH);
5355
5356                 va_start(ap, format);
5357                 g_vsnprintf(fi->rep->representation,
5358                         ITEM_LABEL_LENGTH, format, ap);
5359                 va_end(ap);
5360                 g_strlcat(fi->rep->representation, representation, ITEM_LABEL_LENGTH);
5361         }
5362 }
5363
5364 void
5365 proto_item_set_len(proto_item *pi, const gint length)
5366 {
5367         field_info *fi;
5368
5369         TRY_TO_FAKE_THIS_REPR_VOID(pi);
5370
5371         fi = PITEM_FINFO(pi);
5372         if (fi == NULL)
5373                 return;
5374
5375         DISSECTOR_ASSERT(length >= 0);
5376         fi->length = length;
5377
5378         /*
5379          * You cannot just make the "len" field of a GByteArray
5380          * larger, if there's no data to back that length;
5381          * you can only make it smaller.
5382          */
5383         if (fi->value.ftype->ftype == FT_BYTES && length <= (gint)fi->value.value.bytes->len)
5384                 fi->value.value.bytes->len = length;
5385 }
5386
5387 /*
5388  * Sets the length of the item based on its start and on the specified
5389  * offset, which is the offset past the end of the item; as the start
5390  * in the item is relative to the beginning of the data source tvbuff,
5391  * we need to pass in a tvbuff - the end offset is relative to the beginning
5392  * of that tvbuff.
5393  */
5394 void
5395 proto_item_set_end(proto_item *pi, tvbuff_t *tvb, gint end)
5396 {
5397         field_info *fi;
5398
5399         TRY_TO_FAKE_THIS_REPR_VOID(pi);
5400
5401         fi = PITEM_FINFO(pi);
5402         if (fi == NULL)
5403                 return;
5404
5405         end += tvb_raw_offset(tvb);
5406         DISSECTOR_ASSERT(end >= fi->start);
5407         fi->length = end - fi->start;
5408 }
5409
5410 int
5411 proto_item_get_len(const proto_item *pi)
5412 {
5413         field_info *fi = PITEM_FINFO(pi);
5414         return fi ? fi->length : -1;
5415 }
5416
5417 proto_tree *
5418 proto_tree_create_root(packet_info *pinfo)
5419 {
5420         proto_node *pnode;
5421
5422         /* Initialize the proto_node */
5423         pnode = g_slice_new(proto_tree);
5424         PROTO_NODE_INIT(pnode);
5425         pnode->parent = NULL;
5426         PNODE_FINFO(pnode) = NULL;
5427         pnode->tree_data = g_slice_new(tree_data_t);
5428
5429         /* Make sure we can access pinfo everywhere */
5430         pnode->tree_data->pinfo = pinfo;
5431
5432         /* Don't initialize the tree_data_t. Wait until we know we need it */
5433         pnode->tree_data->interesting_hfids = NULL;
5434
5435         /* Set the default to FALSE so it's easier to
5436          * find errors; if we expect to see the protocol tree
5437          * but for some reason the default 'visible' is not
5438          * changed, then we'll find out very quickly. */
5439         pnode->tree_data->visible = FALSE;
5440
5441         /* Make sure that we fake protocols (if possible) */
5442         pnode->tree_data->fake_protocols = TRUE;
5443
5444         /* Keep track of the number of children */
5445         pnode->tree_data->count = 0;
5446
5447         return (proto_tree *)pnode;
5448 }
5449
5450
5451 /* "prime" a proto_tree with a single hfid that a dfilter
5452  * is interested in. */
5453 void
5454 proto_tree_prime_hfid(proto_tree *tree _U_, const gint hfid)
5455 {
5456         header_field_info *hfinfo;
5457
5458         PROTO_REGISTRAR_GET_NTH(hfid, hfinfo);
5459         /* this field is referenced by a filter so increase the refcount.
5460            also increase the refcount for the parent, i.e the protocol.
5461         */
5462         hfinfo->ref_type = HF_REF_TYPE_DIRECT;
5463         /* only increase the refcount if there is a parent.
5464            if this is a protocol and not a field then parent will be -1
5465            and there is no parent to add any refcounting for.
5466         */
5467         if (hfinfo->parent != -1) {
5468                 header_field_info *parent_hfinfo;
5469                 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
5470
5471                 /* Mark parent as indirectly referenced unless it is already directly
5472                  * referenced, i.e. the user has specified the parent in a filter.
5473                  */
5474                 if (parent_hfinfo->ref_type != HF_REF_TYPE_DIRECT)
5475                         parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
5476         }
5477 }
5478
5479 proto_tree *
5480 proto_item_add_subtree(proto_item *pi,  const gint idx) {
5481         field_info *fi;
5482
5483         if (!pi)
5484                 return NULL;
5485
5486         DISSECTOR_ASSERT(idx >= 0 && idx < num_tree_types);
5487
5488         fi = PITEM_FINFO(pi);
5489         if (!fi)
5490                 return (proto_tree *)pi;
5491
5492         fi->tree_type = idx;
5493
5494         return (proto_tree *)pi;
5495 }
5496
5497 proto_tree *
5498 proto_item_get_subtree(proto_item *pi) {
5499         field_info *fi;
5500
5501         if (!pi)
5502                 return NULL;
5503         fi = PITEM_FINFO(pi);
5504         if ( (!fi) || (fi->tree_type == -1) )
5505                 return NULL;
5506         return (proto_tree *)pi;
5507 }
5508
5509 proto_item *
5510 proto_item_get_parent(const proto_item *ti) {
5511         if (!ti)
5512                 return NULL;
5513         return ti->parent;
5514 }
5515
5516 proto_item *
5517 proto_item_get_parent_nth(proto_item *ti, int gen) {
5518         if (!ti)
5519                 return NULL;
5520         while (gen--) {
5521                 ti = ti->parent;
5522                 if (!ti)
5523                         return NULL;
5524         }
5525         return ti;
5526 }
5527
5528
5529 proto_item *
5530 proto_tree_get_parent(proto_tree *tree) {
5531         if (!tree)
5532                 return NULL;
5533         return (proto_item *)tree;
5534 }
5535
5536 proto_tree *
5537 proto_tree_get_parent_tree(proto_tree *tree) {
5538         if (!tree)
5539                 return NULL;
5540
5541         /* we're the root tree, there's no parent
5542            return ourselves so the caller has at least a tree to attach to */
5543         if (!tree->parent)
5544                 return tree;
5545
5546         return (proto_tree *)tree->parent;
5547 }
5548
5549 proto_tree *
5550 proto_tree_get_root(proto_tree *tree) {
5551         if (!tree)
5552                 return NULL;
5553         while (tree->parent) {
5554                 tree = tree->parent;
5555         }
5556         return tree;
5557 }
5558
5559 void
5560 proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
5561                      proto_item *item_to_move)
5562 {
5563
5564         /* Revert part of: https://code.wireshark.org/review/gitweb?p=wireshark.git;a=commit;h=00c05ed3fdfa9287422e6e1fc9bd6ea8b31ca4ee
5565          * See https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=5500
5566          */
5567         /* This function doesn't generate any values. It only reorganizes the prococol tree
5568          * so we can bail out immediately if it isn't visible. */
5569         if (!tree || !PTREE_DATA(tree)->visible)
5570                 return;
5571
5572         DISSECTOR_ASSERT(item_to_move->parent == tree);
5573         DISSECTOR_ASSERT(fixed_item->parent == tree);
5574
5575         /*** cut item_to_move out ***/
5576
5577         /* is item_to_move the first? */
5578         if (tree->first_child == item_to_move) {
5579                 /* simply change first child to next */
5580                 tree->first_child = item_to_move->next;
5581
5582                 DISSECTOR_ASSERT(tree->last_child != item_to_move);
5583         } else {
5584                 proto_item *curr_item;
5585                 /* find previous and change it's next */
5586                 for(curr_item = tree->first_child; curr_item != NULL; curr_item = curr_item->next) {
5587                         if (curr_item->next == item_to_move) {
5588                                 break;
5589                         }
5590                 }
5591
5592                 DISSECTOR_ASSERT(curr_item);
5593
5594                 curr_item->next = item_to_move->next;
5595
5596                 /* fix last_child if required */
5597                 if (tree->last_child == item_to_move) {
5598                         tree->last_child = curr_item;
5599                 }
5600         }
5601
5602         /*** insert to_move after fixed ***/
5603         item_to_move->next = fixed_item->next;
5604         fixed_item->next = item_to_move;
5605         if (tree->last_child == fixed_item) {
5606                 tree->last_child = item_to_move;
5607         }
5608 }
5609
5610 void
5611 proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, gint start,
5612                         const gint length)
5613 {
5614         field_info *fi;
5615
5616         if (tree == NULL)
5617                 return;
5618
5619         fi = PTREE_FINFO(tree);
5620         if (fi == NULL)
5621                 return;
5622
5623         start += tvb_raw_offset(tvb);
5624         DISSECTOR_ASSERT(start >= 0);
5625         DISSECTOR_ASSERT(length >= 0);
5626
5627         fi->appendix_start = start;
5628         fi->appendix_length = length;
5629 }
5630
5631 int
5632 proto_register_protocol(const char *name, const char *short_name,
5633                         const char *filter_name)
5634 {
5635         protocol_t *protocol;
5636         const protocol_t *existing_protocol = NULL;
5637         header_field_info *hfinfo;
5638         int proto_id;
5639         const char *existing_name;
5640         gint *key;
5641         guint i;
5642         gchar c;
5643         gboolean found_invalid;
5644
5645         /*
5646          * Make sure there's not already a protocol with any of those
5647          * names.  Crash if there is, as that's an error in the code
5648          * or an inappropriate plugin.
5649          * This situation has to be fixed to not register more than one
5650          * protocol with the same name.
5651          *
5652          * This is done by reducing the number of strcmp (and alike) calls
5653          * as much as possible, as this significally slows down startup time.
5654          *
5655          * Drawback: As a hash value is used to reduce insert time,
5656          * this might lead to a hash collision.
5657          * However, although we have somewhat over 1000 protocols, we're using
5658          * a 32 bit int so this is very, very unlikely.
5659          */
5660
5661         key  = (gint *)g_malloc (sizeof(gint));
5662         *key = wrs_str_hash(name);
5663
5664         existing_name = (const char *)g_hash_table_lookup(proto_names, key);
5665         if (existing_name != NULL) {
5666                 /* g_error will terminate the program */
5667                 g_error("Duplicate protocol name \"%s\"!"
5668                         " This might be caused by an inappropriate plugin or a development error.", name);
5669         }
5670         g_hash_table_insert(proto_names, key, (gpointer)name);
5671
5672         existing_protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
5673         if (existing_protocol != NULL) {
5674                 g_error("Duplicate protocol short_name \"%s\"!"
5675                         " This might be caused by an inappropriate plugin or a development error.", short_name);
5676         }
5677
5678         found_invalid = FALSE;
5679         for (i = 0; filter_name[i]; i++) {
5680                 c = filter_name[i];
5681                 if (!(g_ascii_islower(c) || g_ascii_isdigit(c) || c == '-' || c == '_' || c == '.')) {
5682                         found_invalid = TRUE;
5683                 }
5684         }
5685         if (found_invalid) {
5686                 g_error("Protocol filter name \"%s\" has one or more invalid characters."
5687                         " Allowed are lower characters, digits, '-', '_' and '.'."
5688                         " This might be caused by an inappropriate plugin or a development error.", filter_name);
5689         }
5690         existing_protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
5691         if (existing_protocol != NULL) {
5692                 g_error("Duplicate protocol filter_name \"%s\"!"
5693                         " This might be caused by an inappropriate plugin or a development error.", filter_name);
5694         }
5695
5696         /* Add this protocol to the list of known protocols; the list
5697            is sorted by protocol short name. */
5698         protocol = g_new(protocol_t, 1);
5699         protocol->name = name;
5700         protocol->short_name = short_name;
5701         protocol->filter_name = filter_name;
5702         protocol->fields = g_ptr_array_new();
5703         protocol->is_enabled = TRUE; /* protocol is enabled by default */
5704         protocol->enabled_by_default = TRUE; /* see previous comment */
5705         protocol->can_toggle = TRUE;
5706         protocol->heur_list = NULL;
5707         /* list will be sorted later by name, when all protocols completed registering */
5708         protocols = g_list_prepend(protocols, protocol);
5709         g_hash_table_insert(proto_filter_names, (gpointer)filter_name, protocol);
5710         g_hash_table_insert(proto_short_names, (gpointer)short_name, protocol);
5711
5712         /* Here we allocate a new header_field_info struct */
5713         hfinfo = g_slice_new(header_field_info);
5714         hfinfo->name = name;
5715         hfinfo->abbrev = filter_name;
5716         hfinfo->type = FT_PROTOCOL;
5717         hfinfo->display = BASE_NONE;
5718         hfinfo->strings = protocol;
5719         hfinfo->bitmask = 0;
5720         hfinfo->ref_type = HF_REF_TYPE_NONE;
5721         hfinfo->blurb = NULL;
5722         hfinfo->parent = -1; /* this field differentiates protos and fields */
5723
5724         proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
5725         protocol->proto_id = proto_id;
5726         return proto_id;
5727 }
5728
5729 gboolean
5730 proto_deregister_protocol(const char *short_name)
5731 {
5732         protocol_t *protocol;
5733         header_field_info *hfinfo;
5734         int proto_id;
5735         gint key;
5736         guint i;
5737
5738         proto_id = proto_get_id_by_short_name(short_name);
5739         protocol = find_protocol_by_id(proto_id);
5740         if (protocol == NULL)
5741                 return FALSE;
5742
5743         key = wrs_str_hash(protocol->name);
5744         g_hash_table_remove(proto_names, &key);
5745
5746         g_hash_table_remove(proto_short_names, (gpointer)short_name);
5747         g_hash_table_remove(proto_filter_names, (gpointer)protocol->filter_name);
5748
5749         for (i = 0; i < protocol->fields->len; i++) {
5750                 hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i);
5751                 hfinfo_remove_from_gpa_name_map(hfinfo);
5752                 expert_deregister_expertinfo(hfinfo->abbrev);
5753                 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
5754         }
5755         g_ptr_array_free(protocol->fields, TRUE);
5756         protocol->fields = NULL;
5757
5758         /* Remove this protocol from the list of known protocols */
5759         protocols = g_list_remove(protocols, protocol);
5760
5761         g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
5762         g_hash_table_steal(gpa_name_map, protocol->filter_name);
5763
5764         g_free(last_field_name);
5765         last_field_name = NULL;
5766
5767         return TRUE;
5768 }
5769
5770 /*
5771  * Routines to use to iterate over the protocols.
5772  * The argument passed to the iterator routines is an opaque cookie to
5773  * their callers; it's the GList pointer for the current element in
5774  * the list.
5775  * The ID of the protocol is returned, or -1 if there is no protocol.
5776  */
5777 int
5778 proto_get_first_protocol(void **cookie)
5779 {
5780         protocol_t *protocol;
5781
5782         if (protocols == NULL)
5783                 return -1;
5784         *cookie = protocols;
5785         protocol = (protocol_t *)protocols->data;
5786         return protocol->proto_id;
5787 }
5788
5789 int
5790 proto_get_data_protocol(void *cookie)
5791 {
5792         GList *list_item = (GList *)cookie;
5793
5794         protocol_t *protocol = (protocol_t *)list_item->data;
5795         return protocol->proto_id;
5796 }
5797
5798 int
5799 proto_get_next_protocol(void **cookie)
5800 {
5801         GList      *list_item = (GList *)*cookie;
5802         protocol_t *protocol;
5803
5804         list_item = g_list_next(list_item);
5805         if (list_item == NULL)
5806                 return -1;
5807         *cookie = list_item;
5808         protocol = (protocol_t *)list_item->data;
5809         return protocol->proto_id;
5810 }
5811
5812 /* XXX: Unfortunately certain functions in proto_hier_tree_model.c
5813         assume that the cookie stored by
5814         proto_get_(first|next)_protocol_field() will never have a
5815         value of NULL. So, to preserve this semantic, the cookie value
5816         below is adjusted so that the cookie value stored is 1 + the
5817         current (zero-based) array index.
5818 */
5819 header_field_info *
5820 proto_get_first_protocol_field(const int proto_id, void **cookie)
5821 {
5822         protocol_t *protocol = find_protocol_by_id(proto_id);
5823
5824         if ((protocol == NULL) || (protocol->fields->len == 0))
5825                 return NULL;
5826
5827         *cookie = GUINT_TO_POINTER(0 + 1);
5828         return (header_field_info *)g_ptr_array_index(protocol->fields, 0);
5829 }
5830
5831 header_field_info *
5832 proto_get_next_protocol_field(const int proto_id, void **cookie)
5833 {
5834         protocol_t *protocol = find_protocol_by_id(proto_id);
5835         guint       i        = GPOINTER_TO_UINT(*cookie) - 1;
5836
5837         i++;
5838
5839         if (i >= protocol->fields->len)
5840                 return NULL;
5841
5842         *cookie = GUINT_TO_POINTER(i + 1);
5843         return (header_field_info *)g_ptr_array_index(protocol->fields, i);
5844 }
5845
5846 protocol_t *
5847 find_protocol_by_id(const int proto_id)
5848 {
5849         header_field_info *hfinfo;
5850
5851         if (proto_id < 0)
5852                 return NULL;
5853
5854         PROTO_REGISTRAR_GET_NTH(proto_id, hfinfo);
5855         DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_PROTOCOL);
5856         return (protocol_t *)hfinfo->strings;
5857 }
5858
5859 int
5860 proto_get_id(const protocol_t *protocol)
5861 {
5862         return protocol->proto_id;
5863 }
5864
5865 gboolean
5866 proto_name_already_registered(const gchar *name)
5867 {
5868         gint key;
5869
5870         DISSECTOR_ASSERT_HINT(name, "No name present");
5871
5872         key = wrs_str_hash(name);
5873         if (g_hash_table_lookup(proto_names, &key) != NULL)
5874                 return TRUE;
5875         return FALSE;
5876 }
5877
5878 int
5879 proto_get_id_by_filter_name(const gchar *filter_name)
5880 {
5881         const protocol_t *protocol = NULL;
5882
5883         DISSECTOR_ASSERT_HINT(filter_name, "No filter name present");
5884
5885         protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
5886
5887         if (protocol == NULL)
5888                 return -1;
5889         return protocol->proto_id;
5890 }
5891
5892 int
5893 proto_get_id_by_short_name(const gchar *short_name)
5894 {
5895         const protocol_t *protocol = NULL;
5896
5897         DISSECTOR_ASSERT_HINT(short_name, "No short name present");
5898
5899         protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
5900
5901         if (protocol == NULL)
5902                 return -1;
5903         return protocol->proto_id;
5904 }
5905
5906 const char *
5907 proto_get_protocol_name(const int proto_id)
5908 {
5909         protocol_t *protocol;
5910
5911         protocol = find_protocol_by_id(proto_id);
5912
5913         if (protocol == NULL)
5914                 return NULL;
5915         return protocol->name;
5916 }
5917
5918 const char *
5919 proto_get_protocol_short_name(const protocol_t *protocol)
5920 {
5921         if (protocol == NULL)
5922                 return "(none)";
5923         return protocol->short_name;
5924 }
5925
5926 const char *
5927 proto_get_protocol_long_name(const protocol_t *protocol)
5928 {
5929         if (protocol == NULL)
5930                 return "(none)";
5931         return protocol->name;
5932 }
5933
5934 const char *
5935 proto_get_protocol_filter_name(const int proto_id)
5936 {
5937         protocol_t *protocol;
5938
5939         protocol = find_protocol_by_id(proto_id);
5940         if (protocol == NULL)
5941                 return "(none)";
5942         return protocol->filter_name;
5943 }
5944
5945 void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
5946 {
5947         heur_dtbl_entry_t* heuristic_dissector;
5948
5949         if (protocol == NULL)
5950                 return;
5951
5952         heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
5953         if (heuristic_dissector != NULL)
5954         {
5955                 protocol->heur_list = g_list_append (protocol->heur_list, heuristic_dissector);
5956         }
5957 }
5958
5959 void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, gpointer user_data)
5960 {
5961         if (protocol == NULL)
5962                 return;
5963
5964         g_list_foreach(protocol->heur_list, func, user_data);
5965 }
5966
5967 void
5968 proto_get_frame_protocols(const wmem_list_t *layers, gboolean *is_ip,
5969                           gboolean *is_tcp, gboolean *is_udp,
5970                           gboolean *is_sctp, gboolean *is_ssl,
5971                           gboolean *is_rtp,
5972                           gboolean *is_lte_rlc)
5973 {
5974         wmem_list_frame_t *protos = wmem_list_head(layers);
5975         int         proto_id;
5976         const char *proto_name;
5977
5978         /* Walk the list of a available protocols in the packet and
5979            find "major" ones. */
5980         /* It might make more sense to assemble and return a bitfield. */
5981         while (protos != NULL)
5982         {
5983                 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos));
5984                 proto_name = proto_get_protocol_filter_name(proto_id);
5985
5986                 if (is_ip && ((!strcmp(proto_name, "ip")) ||
5987                               (!strcmp(proto_name, "ipv6")))) {
5988                         *is_ip = TRUE;
5989                 } else if (is_tcp && !strcmp(proto_name, "tcp")) {
5990                         *is_tcp = TRUE;
5991                 } else if (is_udp && !strcmp(proto_name, "udp")) {
5992                         *is_udp = TRUE;
5993                 } else if (is_sctp && !strcmp(proto_name, "sctp")) {
5994                         *is_sctp = TRUE;
5995                 } else if (is_ssl && !strcmp(proto_name, "ssl")) {
5996                         *is_ssl = TRUE;
5997                 } else if (is_rtp && !strcmp(proto_name, "rtp")) {
5998                         *is_rtp = TRUE;
5999                 } else if (is_lte_rlc && !strcmp(proto_name, "rlc-lte")) {
6000                         *is_lte_rlc = TRUE;
6001                 }
6002
6003                 protos = wmem_list_frame_next(protos);
6004         }
6005 }
6006
6007 gboolean
6008 proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
6009 {
6010         wmem_list_frame_t *protos = wmem_list_head(layers);
6011         int         proto_id;
6012         const char *name;
6013
6014         /* Walk the list of a available protocols in the packet and
6015            find "major" ones. */
6016         /* It might make more sense to assemble and return a bitfield. */
6017         while (protos != NULL)
6018         {
6019                 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos));
6020                 name = proto_get_protocol_filter_name(proto_id);
6021
6022                 if (!strcmp(name, proto_name))
6023                 {
6024                         return TRUE;
6025                 }
6026
6027                 protos = wmem_list_frame_next(protos);
6028         }
6029
6030         return FALSE;
6031 }
6032
6033
6034 gboolean
6035 proto_is_protocol_enabled(const protocol_t *protocol)
6036 {
6037         return protocol->is_enabled;
6038 }
6039
6040 gboolean
6041 proto_can_toggle_protocol(const int proto_id)
6042 {
6043         protocol_t *protocol;
6044
6045         protocol = find_protocol_by_id(proto_id);
6046         return protocol->can_toggle;
6047 }
6048
6049 void
6050 proto_disable_by_default(const int proto_id)
6051 {
6052         protocol_t *protocol;
6053
6054         protocol = find_protocol_by_id(proto_id);
6055         DISSECTOR_ASSERT(protocol->can_toggle);
6056         protocol->is_enabled = FALSE;
6057         protocol->enabled_by_default = FALSE;
6058 }
6059
6060 void
6061 proto_set_decoding(const int proto_id, const gboolean enabled)
6062 {
6063         protocol_t *protocol;
6064
6065         protocol = find_protocol_by_id(proto_id);
6066         DISSECTOR_ASSERT(protocol->can_toggle);
6067         protocol->is_enabled = enabled;
6068 }
6069
6070 void
6071 proto_enable_all(void)
6072 {
6073         protocol_t *protocol;
6074         GList      *list_item = protocols;
6075
6076         if (protocols == NULL)
6077                 return;
6078
6079         while (list_item) {
6080                 protocol = (protocol_t *)list_item->data;
6081                 if (protocol->can_toggle && protocol->enabled_by_default)
6082                         protocol->is_enabled = TRUE;
6083                 list_item = g_list_next(list_item);
6084         }
6085 }
6086
6087 void
6088 proto_set_cant_toggle(const int proto_id)
6089 {
6090         protocol_t *protocol;
6091
6092         protocol = find_protocol_by_id(proto_id);
6093         protocol->can_toggle = FALSE;
6094 }
6095
6096 static int
6097 proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
6098 {
6099         if (proto != NULL) {
6100                 g_ptr_array_add(proto->fields, hfi);
6101         }
6102
6103         return proto_register_field_init(hfi, parent);
6104 }
6105
6106 /* for use with static arrays only, since we don't allocate our own copies
6107 of the header_field_info struct contained within the hf_register_info struct */
6108 void
6109 proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
6110 {
6111         hf_register_info *ptr = hf;
6112         protocol_t       *proto;
6113         int               i;
6114
6115         proto = find_protocol_by_id(parent);
6116         for (i = 0; i < num_records; i++, ptr++) {
6117                 /*
6118                  * Make sure we haven't registered this yet.
6119                  * Most fields have variables associated with them
6120                  * that are initialized to -1; some have array elements,
6121                  * or possibly uninitialized variables, so we also allow
6122                  * 0 (which is unlikely to be the field ID we get back
6123                  * from "proto_register_field_init()").
6124                  */
6125                 if (*ptr->p_id != -1 && *ptr->p_id != 0) {
6126                         fprintf(stderr,
6127                                 "Duplicate field detected in call to proto_register_field_array: %s is already registered\n",
6128                                 ptr->hfinfo.abbrev);
6129                         return;
6130                 }
6131
6132                 *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
6133         }
6134 }
6135
6136 void
6137 proto_register_fields_section(const int parent, header_field_info *hfi, const int num_records)
6138 {
6139         int               i;
6140         protocol_t       *proto;
6141
6142         proto = find_protocol_by_id(parent);
6143         for (i = 0; i < num_records; i++) {
6144                 /*
6145                  * Make sure we haven't registered this yet.
6146                  */
6147                 if (hfi[i].id != -1) {
6148                         fprintf(stderr,
6149                                 "Duplicate field detected in call to proto_register_fields: %s is already registered\n",
6150                                 hfi[i].abbrev);
6151                         return;
6152                 }
6153
6154                 proto_register_field_common(proto, &hfi[i], parent);
6155         }
6156 }
6157
6158 void
6159 proto_register_fields_manual(const int parent, header_field_info **hfi, const int num_records)
6160 {
6161         int               i;
6162         protocol_t       *proto;
6163
6164         proto = find_protocol_by_id(parent);
6165         for (i = 0; i < num_records; i++) {
6166                 /*
6167                  * Make sure we haven't registered this yet.
6168                  */
6169                 if (hfi[i]->id != -1) {
6170                         fprintf(stderr,
6171                                 "Duplicate field detected in call to proto_register_fields: %s is already registered\n",
6172                                 hfi[i]->abbrev);
6173                         return;
6174                 }
6175
6176                 proto_register_field_common(proto, hfi[i], parent);
6177         }
6178 }
6179
6180 /* deregister already registered fields */
6181 void
6182 proto_deregister_field (const int parent, gint hf_id)
6183 {
6184         header_field_info *hfi;
6185         protocol_t       *proto;
6186         guint             i;
6187
6188         g_free(last_field_name);
6189         last_field_name = NULL;
6190
6191         if (hf_id == -1 || hf_id == 0)
6192                 return;
6193
6194         proto = find_protocol_by_id (parent);
6195         if (!proto || proto->fields->len == 0) {
6196                 return;
6197         }
6198
6199         for (i = 0; i < proto->fields->len; i++) {
6200                 hfi = (header_field_info *)g_ptr_array_index(proto->fields, i);
6201                 if (hfi->id == hf_id) {
6202                         /* Found the hf_id in this protocol */
6203                         g_hash_table_steal(gpa_name_map, hfi->abbrev);
6204                         g_ptr_array_remove_index_fast(proto->fields, i);
6205                         g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
6206                         return;
6207                 }
6208         }
6209 }
6210
6211 void
6212 proto_add_deregistered_data (void *data)
6213 {
6214         g_ptr_array_add(deregistered_data, data);
6215 }
6216
6217 static void
6218 free_deregistered_field (gpointer data, gpointer user_data _U_)
6219 {
6220         header_field_info *hfi = (header_field_info *) data;
6221         gint hf_id = hfi->id;
6222
6223         g_free((char *)hfi->name);
6224         g_free((char *)hfi->abbrev);
6225         g_free((char *)hfi->blurb);
6226
6227         if (hfi->strings) {
6228                 switch (hfi->type) {
6229                         case FT_FRAMENUM:
6230                                 /* This is just an integer represented as a pointer */
6231                                 break;
6232                         case FT_PROTOCOL: {
6233                                 protocol_t *protocol = (protocol_t *)hfi->strings;
6234                                 g_free((gchar *)protocol->short_name);
6235                                 break;
6236                         }
6237                         case FT_BOOLEAN: {
6238                                 true_false_string *tf = (true_false_string *)hfi->strings;
6239                                 g_free ((gchar *)tf->true_string);
6240                                 g_free ((gchar *)tf->false_string);
6241                                 break;
6242                         }
6243                         case FT_UINT64:
6244                         case FT_INT64: {
6245                                 val64_string *vs64 = (val64_string *)hfi->strings;
6246                                 while (vs64->strptr) {
6247                                         g_free((gchar *)vs64->strptr);
6248                                         vs64++;
6249                                 }
6250                                 break;
6251                         }
6252                         default: {
6253                                 /* Other Integer types */
6254                                 value_string *vs = (value_string *)hfi->strings;
6255                                 while (vs->strptr) {
6256                                         g_free((gchar *)vs->strptr);
6257                                         vs++;
6258                                 }
6259                                 break;
6260                         }
6261                 }
6262                 if (hfi->type != FT_FRAMENUM) {
6263                         g_free((void *)hfi->strings);
6264                 }
6265         }
6266
6267         if (hfi->parent == -1)
6268                 g_slice_free(header_field_info, hfi);
6269
6270         gpa_hfinfo.hfi[hf_id] = NULL; /* Invalidate this hf_id / proto_id */
6271 }
6272
6273 static void
6274 free_deregistered_data (gpointer data, gpointer user_data _U_)
6275 {
6276         g_free (data);
6277 }
6278
6279 /* free deregistered fields and data */
6280 void
6281 proto_free_deregistered_fields (void)
6282 {
6283         expert_free_deregistered_expertinfos();
6284
6285         g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL);
6286         g_ptr_array_free(deregistered_fields, TRUE);
6287         deregistered_fields = g_ptr_array_new();
6288
6289         g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL);
6290         g_ptr_array_free(deregistered_data, TRUE);
6291         deregistered_data = g_ptr_array_new();
6292 }
6293
6294 /* chars allowed in field abbrev */
6295 static
6296 const guint8 fld_abbrev_chars[256] = {
6297         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00-0x0F */
6298         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10-0x1F */
6299         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, /* 0x20-0x2F '-', '.'      */
6300         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 0x30-0x3F '0'-'9'       */
6301         0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40-0x4F 'A'-'O'       */
6302         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 0x50-0x5F 'P'-'Z', '_' */
6303         0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x60-0x6F 'a'-'o'       */
6304         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 0x70-0x7F 'p'-'z'       */
6305         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80-0x8F */
6306         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90-0x9F */
6307         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xA0-0xAF */
6308         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xB0-0xBF */
6309         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xC0-0xCF */
6310         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xD0-0xDF */
6311         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xE0-0xEF */
6312         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xF0-0xFF */
6313 };
6314
6315 static const value_string hf_display[] = {
6316         { BASE_NONE,                      "BASE_NONE"                      },
6317         { BASE_DEC,                       "BASE_DEC"                       },
6318         { BASE_HEX,                       "BASE_HEX"                       },
6319         { BASE_OCT,                       "BASE_OCT"                       },
6320         { BASE_DEC_HEX,                   "BASE_DEC_HEX"                   },
6321         { BASE_HEX_DEC,                   "BASE_HEX_DEC"                   },
6322         { BASE_CUSTOM,                    "BASE_CUSTOM"                    },
6323         { BASE_NONE|BASE_RANGE_STRING,    "BASE_NONE|BASE_RANGE_STRING"    },
6324         { BASE_DEC|BASE_RANGE_STRING,     "BASE_DEC|BASE_RANGE_STRING"     },
6325         { BASE_HEX|BASE_RANGE_STRING,     "BASE_HEX|BASE_RANGE_STRING"     },
6326         { BASE_OCT|BASE_RANGE_STRING,     "BASE_OCT|BASE_RANGE_STRING"     },
6327         { BASE_DEC_HEX|BASE_RANGE_STRING, "BASE_DEC_HEX|BASE_RANGE_STRING" },
6328         { BASE_HEX_DEC|BASE_RANGE_STRING, "BASE_HEX_DEC|BASE_RANGE_STRING" },
6329         { BASE_CUSTOM|BASE_RANGE_STRING,  "BASE_CUSTOM|BASE_RANGE_STRING"  },
6330         { BASE_NONE|BASE_VAL64_STRING,    "BASE_NONE|BASE_VAL64_STRING"    },
6331         { BASE_DEC|BASE_VAL64_STRING,     "BASE_DEC|BASE_VAL64_STRING"     },
6332         { BASE_HEX|BASE_VAL64_STRING,     "BASE_HEX|BASE_VAL64_STRING"     },
6333         { BASE_OCT|BASE_VAL64_STRING,     "BASE_OCT|BASE_VAL64_STRING"     },
6334         { BASE_DEC_HEX|BASE_VAL64_STRING, "BASE_DEC_HEX|BASE_VAL64_STRING" },
6335         { BASE_HEX_DEC|BASE_VAL64_STRING, "BASE_HEX_DEC|BASE_VAL64_STRING" },
6336         { BASE_CUSTOM|BASE_VAL64_STRING,  "BASE_CUSTOM|BASE_VAL64_STRING"  },
6337         /* Alias: BASE_NONE { BASE_FLOAT,                       "BASE_FLOAT" }, */
6338         /* Alias: BASE_NONE { STR_ASCII,                          "STR_ASCII" }, */
6339         { STR_UNICODE,                    "STR_UNICODE" },
6340         { ABSOLUTE_TIME_LOCAL,            "ABSOLUTE_TIME_LOCAL"            },
6341         { ABSOLUTE_TIME_UTC,              "ABSOLUTE_TIME_UTC"              },
6342         { ABSOLUTE_TIME_DOY_UTC,          "ABSOLUTE_TIME_DOY_UTC"          },
6343         { BASE_PT_UDP,                    "BASE_PT_UDP"                    },
6344         { BASE_PT_TCP,                    "BASE_PT_TCP"                    },
6345         { BASE_PT_DCCP,                   "BASE_PT_DCCP"                   },
6346         { BASE_PT_SCTP,                   "BASE_PT_SCTP"                   },
6347         { 0,                              NULL } };
6348
6349 const char* proto_field_display_to_string(int field_display)
6350 {
6351     return val_to_str_const(field_display, hf_display, "Unknown");
6352 }
6353
6354 static inline port_type
6355 display_to_port_type(field_display_e e)
6356 {
6357         switch (e) {
6358         case BASE_PT_UDP:
6359                 return PT_UDP;
6360         case BASE_PT_TCP:
6361                 return PT_TCP;
6362         case BASE_PT_DCCP:
6363                 return PT_DCCP;
6364         case BASE_PT_SCTP:
6365                 return PT_SCTP;
6366         default:
6367                 break;
6368         }
6369         return PT_NONE;
6370 }
6371
6372 /* temporary function containing assert part for easier profiling */
6373 static void
6374 tmp_fld_check_assert(header_field_info *hfinfo)
6375 {
6376         gchar* tmp_str;
6377
6378         /* The field must have a name (with length > 0) */
6379         if (!hfinfo->name || !hfinfo->name[0]) {
6380                 if (hfinfo->abbrev)
6381                         /* Try to identify the field */
6382                         g_error("Field (abbrev='%s') does not have a name\n",
6383                                 hfinfo->abbrev);
6384                 else
6385                         /* Hum, no luck */
6386                         g_error("Field does not have a name (nor an abbreviation)\n");
6387         }
6388
6389         /* fields with an empty string for an abbreviation aren't filterable */
6390         if (!hfinfo->abbrev || !hfinfo->abbrev[0])
6391                 g_error("Field '%s' does not have an abbreviation\n", hfinfo->name);
6392
6393         /*  These types of fields are allowed to have value_strings,
6394          *  true_false_strings or a protocol_t struct
6395          */
6396         if (hfinfo->strings != NULL && !(
6397                     (hfinfo->type == FT_UINT8)    ||
6398                     (hfinfo->type == FT_UINT16)   ||
6399                     (hfinfo->type == FT_UINT24)   ||
6400                     (hfinfo->type == FT_UINT32)   ||
6401                     (hfinfo->type == FT_UINT40)   ||
6402                     (hfinfo->type == FT_UINT48)   ||
6403                     (hfinfo->type == FT_UINT56)   ||
6404                     (hfinfo->type == FT_UINT64)   ||
6405                     (hfinfo->type == FT_INT8)     ||
6406                     (hfinfo->type == FT_INT16)    ||
6407                     (hfinfo->type == FT_INT24)    ||
6408                     (hfinfo->type == FT_INT32)    ||
6409                     (hfinfo->type == FT_INT40)    ||
6410                     (hfinfo->type == FT_INT48)    ||
6411                     (hfinfo->type == FT_INT56)    ||
6412                     (hfinfo->type == FT_INT64)    ||
6413                     (hfinfo->type == FT_BOOLEAN)  ||
6414                     (hfinfo->type == FT_PROTOCOL) ||
6415                     (hfinfo->type == FT_FRAMENUM) ))
6416                 g_error("Field '%s' (%s) has a 'strings' value but is of type %s"
6417                         " (which is not allowed to have strings)\n",
6418                         hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type));
6419
6420         /* TODO: This check may slow down startup, and output quite a few warnings.
6421            It would be good to be able to enable this (and possibly other checks?)
6422            in non-release builds.   */
6423 #if 0
6424         /* Check for duplicate value_string values.
6425            There are lots that have the same value *and* string, so for now only
6426            report those that have same value but different string. */
6427         if ((hfinfo->strings != NULL) &&
6428             !(hfinfo->display & BASE_RANGE_STRING) &&
6429             !((hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_CUSTOM) &&
6430             (
6431                     (hfinfo->type == FT_UINT8)  ||
6432                     (hfinfo->type == FT_UINT16) ||
6433                     (hfinfo->type == FT_UINT24) ||
6434                     (hfinfo->type == FT_UINT32) ||
6435                     (hfinfo->type == FT_INT8)   ||
6436                     (hfinfo->type == FT_INT16)  ||
6437                     (hfinfo->type == FT_INT24)  ||
6438                     (hfinfo->type == FT_INT32)  ||
6439                     (hfinfo->type == FT_FRAMENUM) )) {
6440
6441                 int n, m;
6442                 const value_string *start_values;
6443                 const value_string *current;
6444
6445                 if (hfinfo->display & BASE_EXT_STRING)
6446                         start_values = VALUE_STRING_EXT_VS_P(((const value_string_ext*)hfinfo->strings));
6447                 else
6448                         start_values = (const value_string*)hfinfo->strings;
6449                 current = start_values;
6450
6451                 for (n=0; current; n++, current++) {
6452                         /* Drop out if we reached the end. */
6453                         if ((current->value == 0) && (current->strptr == NULL)) {
6454                                 break;
6455                         }
6456
6457                         /* Check value against all previous */
6458                         for (m=0; m < n; m++) {
6459                                 /* There are lots of duplicates with the same string,
6460                                    so only report if different... */
6461                                 if ((start_values[m].value == current->value) &&
6462                                     (strcmp(start_values[m].strptr, current->strptr) != 0)) {
6463                                         g_warning("Field '%s' (%s) has a conflicting entry in its"
6464                                                   " value_string: %u is at indices %u (%s) and %u (%s))\n",
6465                                                   hfinfo->name, hfinfo->abbrev,
6466                                                   current->value, m, start_values[m].strptr, n, current->strptr);
6467                                 }
6468                         }
6469                 }
6470         }
6471 #endif
6472
6473
6474         switch (hfinfo->type) {
6475
6476                 case FT_INT8:
6477                 case FT_INT16:
6478                 case FT_INT24:
6479                 case FT_INT32:
6480                 case FT_INT40:
6481                 case FT_INT48:
6482                 case FT_INT56:
6483                 case FT_INT64:
6484                         /*      Hexadecimal and octal are, in printf() and everywhere
6485                          *      else, unsigned so don't allow dissectors to register a
6486                          *      signed field to be displayed unsigned.  (Else how would
6487                          *      we display negative values?)
6488                          */
6489                         switch (hfinfo->display & FIELD_DISPLAY_E_MASK) {
6490                                 case BASE_HEX:
6491                                 case BASE_OCT:
6492                                 case BASE_DEC_HEX:
6493                                 case BASE_HEX_DEC:
6494                                         tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
6495                                         g_error("Field '%s' (%s) is signed (%s) but is being displayed unsigned (%s)\n",
6496                                                 hfinfo->name, hfinfo->abbrev,
6497                                                 ftype_name(hfinfo->type), tmp_str);
6498                                         wmem_free(NULL, tmp_str);
6499                         }
6500                         /* FALL THROUGH */
6501                 case FT_UINT8:
6502                 case FT_UINT16:
6503                 case FT_UINT24:
6504                 case FT_UINT32:
6505                 case FT_UINT40:
6506                 case FT_UINT48:
6507                 case FT_UINT56:
6508                 case FT_UINT64:
6509                         if (IS_BASE_PORT(hfinfo->display)) {
6510                                 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
6511                                 if (hfinfo->type != FT_UINT16) {
6512                                         g_error("Field '%s' (%s) has 'display' value %s but it can only be used with FT_UINT16, not %s\n",
6513                                                 hfinfo->name, hfinfo->abbrev,
6514                                                 tmp_str, ftype_name(hfinfo->type));
6515                                 }
6516                                 if (hfinfo->strings != NULL) {
6517                                         g_error("Field '%s' (%s) is an %s (%s) but has a strings value\n",
6518                                                 hfinfo->name, hfinfo->abbrev,
6519                                                 ftype_name(hfinfo->type), tmp_str);
6520                                 }
6521                                 if (hfinfo->bitmask != 0) {
6522                                         g_error("Field '%s' (%s) is an %s (%s) but has a bitmask\n",
6523                                                 hfinfo->name, hfinfo->abbrev,
6524                                                 ftype_name(hfinfo->type), tmp_str);
6525                                 }
6526                                 wmem_free(NULL, tmp_str);
6527                                 break;
6528                         }
6529
6530                         /*  Require integral types (other than frame number,
6531                          *  which is always displayed in decimal) to have a
6532                          *  number base.
6533                          *
6534                          *  If the display value is BASE_NONE and there is a
6535                          *  strings conversion then the dissector writer is
6536                          *  telling us that the field's numerical value is
6537                          *  meaningless; we'll avoid showing the value to the
6538                          *  user.
6539                          */
6540                         switch (hfinfo->display & FIELD_DISPLAY_E_MASK) {
6541                                 case BASE_DEC:
6542                                 case BASE_HEX:
6543                                 case BASE_OCT:
6544                                 case BASE_DEC_HEX:
6545                                 case BASE_HEX_DEC:
6546                                 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
6547                                         break;
6548                                 case BASE_NONE:
6549                                         if (hfinfo->strings == NULL)
6550                                                 g_error("Field '%s' (%s) is an integral value (%s)"
6551                                                         " but is being displayed as BASE_NONE but"
6552                                                         " without a strings conversion",
6553                                                         hfinfo->name, hfinfo->abbrev,
6554                                                         ftype_name(hfinfo->type));
6555                                         break;
6556                                 default:
6557                                         tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
6558                                         g_error("Field '%s' (%s) is an integral value (%s)"
6559                                                 " but is being displayed as %s\n",
6560                                                 hfinfo->name, hfinfo->abbrev,
6561                                                 ftype_name(hfinfo->type), tmp_str);
6562                                         wmem_free(NULL, tmp_str);
6563                         }
6564                         break;
6565                 case FT_BYTES:
6566                         /*  Require bytes to have a "display type" that could
6567                          *  add a character between displayed bytes.
6568                          */
6569                         switch (hfinfo->display & FIELD_DISPLAY_E_MASK) {
6570                                 case BASE_NONE:
6571                                 case SEP_DOT:
6572                                 case SEP_DASH:
6573                                 case SEP_COLON:
6574                                 case SEP_SPACE:
6575                                         break;
6576                                 default:
6577                                         tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
6578                                         g_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",
6579                                                 hfinfo->name, hfinfo->abbrev, tmp_str);
6580                                         wmem_free(NULL, tmp_str);
6581                         }
6582                         if (hfinfo->bitmask != 0)
6583                                 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
6584                                         hfinfo->name, hfinfo->abbrev,
6585                                         ftype_name(hfinfo->type));
6586                         if (hfinfo->strings != NULL)
6587                                 g_error("Field '%s' (%s) is an %s but has a strings value\n",
6588                                         hfinfo->name, hfinfo->abbrev,
6589                                         ftype_name(hfinfo->type));
6590                         break;
6591
6592                 case FT_PROTOCOL:
6593                 case FT_FRAMENUM:
6594                         if (hfinfo->display != BASE_NONE) {
6595                                 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
6596                                 g_error("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE\n",
6597                                         hfinfo->name, hfinfo->abbrev,
6598                                         ftype_name(hfinfo->type), tmp_str);
6599                                 wmem_free(NULL, tmp_str);
6600                         }
6601                         if (hfinfo->bitmask != 0)
6602                                 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
6603                                         hfinfo->name, hfinfo->abbrev,
6604                                         ftype_name(hfinfo->type));
6605                         break;
6606
6607                 case FT_BOOLEAN:
6608                         break;
6609
6610                 case FT_ABSOLUTE_TIME:
6611                         if (!(hfinfo->display == ABSOLUTE_TIME_LOCAL ||
6612                               hfinfo->display == ABSOLUTE_TIME_UTC   ||
6613                               hfinfo->display == ABSOLUTE_TIME_DOY_UTC)) {
6614                                 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
6615                                 g_error("Field '%s' (%s) is a %s but is being displayed as %s instead of as a time\n",
6616                                         hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type), tmp_str);
6617                                 wmem_free(NULL, tmp_str);
6618                         }
6619                         if (hfinfo->bitmask != 0)
6620                                 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
6621                                         hfinfo->name, hfinfo->abbrev,
6622                                         ftype_name(hfinfo->type));
6623                         break;
6624
6625                 case FT_STRING:
6626                 case FT_STRINGZ:
6627                 case FT_UINT_STRING:
6628                 case FT_STRINGZPAD:
6629                         switch (hfinfo->display) {
6630                                 case STR_ASCII:
6631                                 case STR_UNICODE:
6632                                         break;
6633
6634                                 default:
6635                                         tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
6636                                         g_error("Field '%s' (%s) is an string value (%s)"
6637                                                 " but is being displayed as %s\n",
6638                                                 hfinfo->name, hfinfo->abbrev,
6639                                                 ftype_name(hfinfo->type), tmp_str);
6640                                         wmem_free(NULL, tmp_str);
6641                         }
6642
6643                         if (hfinfo->bitmask != 0)
6644                                 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
6645                                         hfinfo->name, hfinfo->abbrev,
6646                                         ftype_name(hfinfo->type));
6647                         if (hfinfo->strings != NULL)
6648                                 g_error("Field '%s' (%s) is an %s but has a strings value\n",
6649                                         hfinfo->name, hfinfo->abbrev,
6650                                         ftype_name(hfinfo->type));
6651                         break;
6652
6653                 case FT_IPv4:
6654                         switch (hfinfo->display) {
6655                                 case BASE_NONE:
6656                                 case BASE_NETMASK:
6657                                         break;
6658
6659                                 default:
6660                                         tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
6661                                         g_error("Field '%s' (%s) is an IPv4 value (%s)"
6662                                                 " but is being displayed as %s\n",
6663                                                 hfinfo->name, hfinfo->abbrev,
6664                                                 ftype_name(hfinfo->type), tmp_str);
6665                                         wmem_free(NULL, tmp_str);
6666                                         break;
6667                         }
6668                         break;
6669                 default:
6670                         if (hfinfo->display != BASE_NONE) {
6671                                 tmp_str = val_to_str_wmem(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
6672                                 g_error("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE\n",
6673                                         hfinfo->name, hfinfo->abbrev,
6674                                         ftype_name(hfinfo->type),
6675                                         tmp_str);
6676                                 wmem_free(NULL, tmp_str);
6677                         }
6678                         if (hfinfo->bitmask != 0)
6679                                 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
6680                                         hfinfo->name, hfinfo->abbrev,
6681                                         ftype_name(hfinfo->type));
6682                         if (hfinfo->strings != NULL)
6683                                 g_error("Field '%s' (%s) is an %s but has a strings value\n",
6684                                         hfinfo->name, hfinfo->abbrev,
6685                                         ftype_name(hfinfo->type));
6686                         break;
6687         }
6688 }
6689
6690 #ifdef ENABLE_CHECK_FILTER
6691 static enum ftenum
6692 _ftype_common(enum ftenum type)
6693 {
6694         switch (type) {
6695                 case FT_INT8:
6696                 case FT_INT16:
6697                 case FT_INT24:
6698                 case FT_INT32:
6699                         return FT_INT32;
6700
6701                 case FT_UINT8:
6702                 case FT_UINT16:
6703                 case FT_UINT24:
6704                 case FT_UINT32:
6705                 case FT_IPXNET:
6706                 case FT_FRAMENUM:
6707                         return FT_UINT32;
6708
6709                 case FT_UINT64:
6710                 case FT_EUI64:
6711                         return FT_UINT64;
6712
6713                 case FT_STRING:
6714                 case FT_STRINGZ:
6715                 case FT_UINT_STRING:
6716                         return FT_STRING;
6717
6718                 case FT_FLOAT:
6719                 case FT_DOUBLE:
6720                         return FT_DOUBLE;
6721
6722                 case FT_BYTES:
6723                 case FT_UINT_BYTES:
6724                 case FT_ETHER:
6725                 case FT_OID:
6726                         return FT_BYTES;
6727
6728                 case FT_ABSOLUTE_TIME:
6729                 case FT_RELATIVE_TIME:
6730                         return FT_ABSOLUTE_TIME;
6731
6732                 default:
6733                         return type;
6734         }
6735 }
6736 #endif
6737
6738 static void
6739 register_type_length_mismatch(void)
6740 {
6741         static ei_register_info ei[] = {
6742                 { &ei_type_length_mismatch_error, { "_ws.type_length.mismatch", PI_MALFORMED, PI_ERROR, "Trying to fetch X with length Y", EXPFILL }},
6743                 { &ei_type_length_mismatch_warn, { "_ws.type_length.mismatch", PI_MALFORMED, PI_WARN, "Trying to fetch X with length Y", EXPFILL }},
6744         };
6745
6746         expert_module_t* expert_type_length_mismatch;
6747
6748         proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
6749
6750         expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
6751         expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei));
6752
6753         /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
6754            disabling them makes no sense. */
6755         proto_set_cant_toggle(proto_type_length_mismatch);
6756 }
6757
6758 static void
6759 register_number_string_decoding_error(void)
6760 {
6761         static ei_register_info ei[] = {
6762                 { &ei_number_string_decoding_failed_error,
6763                         { "_ws.number_string.decoding_error.failed", PI_MALFORMED, PI_ERROR,
6764                           "Failed to decode number from string", EXPFILL
6765                         }
6766                 },
6767                 { &ei_number_string_decoding_erange_error,
6768                         { "_ws.number_string.decoding_error.erange", PI_MALFORMED, PI_ERROR,
6769                           "Decoded number from string is out of valid range", EXPFILL
6770                         }
6771                 },
6772         };
6773
6774         expert_module_t* expert_number_string_decoding_error;
6775
6776         proto_number_string_decoding_error =
6777                 proto_register_protocol("Number-String Decoding Error",
6778                                         "Number-string decoding error",
6779                                         "_ws.number_string.decoding_error");
6780
6781         expert_number_string_decoding_error =
6782                 expert_register_protocol(proto_number_string_decoding_error);
6783         expert_register_field_array(expert_number_string_decoding_error, ei, array_length(ei));
6784
6785         /* "Number-String Decoding Error" isn't really a protocol, it's an error indication;
6786            disabling them makes no sense. */
6787         proto_set_cant_toggle(proto_number_string_decoding_error);
6788 }
6789
6790 #define PROTO_PRE_ALLOC_HF_FIELDS_MEM (178000+PRE_ALLOC_EXPERT_FIELDS_MEM)
6791 static int
6792 proto_register_field_init(header_field_info *hfinfo, const int parent)
6793 {
6794
6795         tmp_fld_check_assert(hfinfo);
6796
6797         hfinfo->parent         = parent;
6798         hfinfo->same_name_next = NULL;
6799         hfinfo->same_name_prev_id = -1;
6800
6801         /* if we always add and never delete, then id == len - 1 is correct */
6802         if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
6803                 if (!gpa_hfinfo.hfi) {
6804                         gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM;
6805                         gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM);
6806                 } else {
6807                         gpa_hfinfo.allocated_len += 1000;
6808                         gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
6809                                                    sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
6810                         /*g_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
6811                 }
6812         }
6813         gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
6814         gpa_hfinfo.len++;
6815         hfinfo->id = gpa_hfinfo.len - 1;
6816
6817         /* if we have real names, enter this field in the name tree */
6818         if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) {
6819
6820                 header_field_info *same_name_next_hfinfo;
6821                 guchar c;
6822
6823                 /* Check that the filter name (abbreviation) is legal;
6824                  * it must contain only alphanumerics, '-', "_", and ".". */
6825                 c = wrs_check_charset(fld_abbrev_chars, hfinfo->abbrev);
6826                 if (c) {
6827                         if (g_ascii_isprint(c))
6828                                 fprintf(stderr, "Invalid character '%c' in filter name '%s'\n", c, hfinfo->abbrev);
6829                         else
6830                                 fprintf(stderr, "Invalid byte \\%03o in filter name '%s'\n", c, hfinfo->abbrev);
6831                         DISSECTOR_ASSERT_NOT_REACHED();
6832                 }
6833
6834                 /* We allow multiple hfinfo's to be registered under the same
6835                  * abbreviation. This was done for X.25, as, depending
6836                  * on whether it's modulo-8 or modulo-128 operation,
6837                  * some bitfield fields may be in different bits of
6838                  * a byte, and we want to be able to refer to that field
6839                  * with one name regardless of whether the packets
6840                  * are modulo-8 or modulo-128 packets. */
6841
6842                 same_name_hfinfo = NULL;
6843
6844                 g_hash_table_insert(gpa_name_map, (gpointer) (hfinfo->abbrev), hfinfo);
6845                 /* GLIB 2.x - if it is already present
6846                  * the previous hfinfo with the same name is saved
6847                  * to same_name_hfinfo by value destroy callback */
6848                 if (same_name_hfinfo) {
6849                         /* There's already a field with this name.
6850                          * Put the current field *before* that field
6851                          * in the list of fields with this name, Thus,
6852                          * we end up with an effectively
6853                          * doubly-linked-list of same-named hfinfo's,
6854                          * with the head of the list (stored in the
6855                          * hash) being the last seen hfinfo.
6856                          */
6857                         same_name_next_hfinfo =
6858                                 same_name_hfinfo->same_name_next;
6859
6860                         hfinfo->same_name_next = same_name_next_hfinfo;
6861                         if (same_name_next_hfinfo)
6862                                 same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
6863
6864                         same_name_hfinfo->same_name_next = hfinfo;
6865                         hfinfo->same_name_prev_id = same_name_hfinfo->id;
6866 #ifdef ENABLE_CHECK_FILTER
6867                         while (same_name_hfinfo) {
6868                                 if (_ftype_common(hfinfo->type) != _ftype_common(same_name_hfinfo->type))
6869                                         fprintf(stderr, "'%s' exists multiple times with NOT compatible types: %s and %s\n", hfinfo->abbrev, ftype_name(hfinfo->type), ftype_name(same_name_hfinfo->type));
6870                                 same_name_hfinfo = same_name_hfinfo->same_name_next;
6871                         }
6872 #endif
6873                 }
6874         }
6875
6876         return hfinfo->id;
6877 }
6878
6879 void
6880 proto_register_subtree_array(gint *const *indices, const int num_indices)
6881 {
6882         int     i;
6883         gint    *const *ptr = indices;
6884
6885         /*
6886          * If we've already allocated the array of tree types, expand
6887          * it; this lets plugins such as mate add tree types after
6888          * the initial startup.  (If we haven't already allocated it,
6889          * we don't allocate it; on the first pass, we just assign
6890          * ett values and keep track of how many we've assigned, and
6891          * when we're finished registering all dissectors we allocate
6892          * the array, so that we do only one allocation rather than
6893          * wasting CPU time and memory by growing the array for each
6894          * dissector that registers ett values.)
6895          */
6896         if (tree_is_expanded != NULL) {
6897                 tree_is_expanded = (guint32 *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(guint32));
6898
6899                 /* set new items to 0 */
6900                 /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of guint32 to 0) */
6901                 for (i = num_tree_types; i < num_tree_types + num_indices; i++)
6902                         tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
6903         }
6904
6905         /*
6906          * Assign "num_indices" subtree numbers starting at "num_tree_types",
6907          * returning the indices through the pointers in the array whose
6908          * first element is pointed to by "indices", and update
6909          * "num_tree_types" appropriately.
6910          */
6911         for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
6912                 if (**ptr != -1) {
6913                         /* g_error will terminate the program */
6914                         g_error("register_subtree_array: subtree item type (ett_...) not -1 !"
6915                                 " This is a development error:"
6916                                 " Either the subtree item type has already been assigned or"
6917                                 " was not initialized to -1.");
6918                 }
6919                 **ptr = num_tree_types;
6920         }
6921 }
6922
6923 static inline gsize
6924 label_concat(char *label_str, gsize pos, const char *str)
6925 {
6926         if (pos < ITEM_LABEL_LENGTH)
6927                 pos += g_strlcpy(label_str + pos, str, ITEM_LABEL_LENGTH - pos);
6928
6929         return pos;
6930 }
6931
6932 static void
6933 label_mark_truncated(char *label_str, gsize name_pos)
6934 {
6935         static const char  trunc_str[] = " [truncated]";
6936         const size_t       trunc_len = sizeof(trunc_str)-1;
6937         gchar             *last_char;
6938
6939         /* ..... field_name: dataaaaaaaaaaaaa
6940          *                 |
6941          *                 ^^^^^ name_pos
6942          *
6943          * ..... field_name [truncated]: dataaaaaaaaaaaaa
6944          *
6945          * name_pos==0 means that we have only data or only a field_name
6946          */
6947
6948         if (name_pos < ITEM_LABEL_LENGTH - trunc_len) {
6949                 memmove(label_str + name_pos + trunc_len, label_str + name_pos, ITEM_LABEL_LENGTH - name_pos - trunc_len);
6950                 memcpy(label_str + name_pos, trunc_str, trunc_len);
6951
6952                 /* in general, label_str is UTF-8
6953                    we can truncate it only at the beginning of a new character
6954                    we go backwards from the byte right after our buffer and
6955                     find the next starting byte of a UTF-8 character, this is
6956                     where we cut
6957                    there's no need to use g_utf8_find_prev_char(), the search
6958                     will always succeed since we copied trunc_str into the
6959                     buffer */
6960                 last_char = g_utf8_prev_char(&label_str[ITEM_LABEL_LENGTH]);
6961                 *last_char = '\0';
6962
6963         } else if (name_pos < ITEM_LABEL_LENGTH)
6964                 g_strlcpy(label_str + name_pos, trunc_str, ITEM_LABEL_LENGTH - name_pos);
6965 }
6966
6967 static gsize
6968 label_fill(char *label_str, gsize pos, const header_field_info *hfinfo, const char *text)
6969 {
6970         gsize name_pos;
6971
6972         /* "%s: %s", hfinfo->name, text */
6973         name_pos = pos = label_concat(label_str, pos, hfinfo->name);
6974         pos = label_concat(label_str, pos, ": ");
6975         pos = label_concat(label_str, pos, text ? text : "(null)");
6976
6977         if (pos >= ITEM_LABEL_LENGTH) {
6978                 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
6979                 label_mark_truncated(label_str, name_pos);
6980         }
6981
6982         return pos;
6983 }
6984
6985 static gsize
6986 label_fill_descr(char *label_str, gsize pos, const header_field_info *hfinfo, const char *text, const char *descr)
6987 {
6988         gsize name_pos;
6989
6990         /* "%s: %s (%s)", hfinfo->name, text, descr */
6991         name_pos = pos = label_concat(label_str, pos, hfinfo->name);
6992         pos = label_concat(label_str, pos, ": ");
6993         pos = label_concat(label_str, pos, text ? text : "(null)");
6994         pos = label_concat(label_str, pos, " (");
6995         pos = label_concat(label_str, pos, descr ? descr : "(null)");
6996         pos = label_concat(label_str, pos, ")");
6997
6998         if (pos >= ITEM_LABEL_LENGTH) {
6999                 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7000                 label_mark_truncated(label_str, name_pos);
7001         }
7002
7003         return pos;
7004 }
7005
7006 void
7007 proto_item_fill_label(field_info *fi, gchar *label_str)
7008 {
7009         header_field_info  *hfinfo;
7010         guint8             *bytes;
7011         guint32             integer;
7012         guint64             integer64;
7013         ipv4_addr_and_mask *ipv4;
7014         e_guid_t           *guid;
7015         guint32             n_addr; /* network-order IPv4 address */
7016         gchar              *name;
7017         address             addr;
7018         char               *addr_str;
7019         char               *tmp;
7020
7021         if (!fi) {
7022                 if (label_str)
7023                         label_str[0]= '\0';
7024                 /* XXX: Check validity of hfinfo->type */
7025                 return;
7026         }
7027
7028         hfinfo = fi->hfinfo;
7029
7030         switch (hfinfo->type) {
7031                 case FT_NONE:
7032                 case FT_PROTOCOL:
7033                         g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH);
7034                         break;
7035
7036                 case FT_BOOLEAN:
7037                         fill_label_boolean(fi, label_str);
7038                         break;
7039
7040                 case FT_BYTES:
7041                 case FT_UINT_BYTES:
7042                         bytes = (guint8 *)fvalue_get(&fi->value);
7043                         if (bytes) {
7044                                 char* str = NULL;
7045                                 switch(hfinfo->display)
7046                                 {
7047                                 case SEP_DOT:
7048                                         str = bytestring_to_str(NULL, bytes, fvalue_length(&fi->value), '.');
7049                                         break;
7050                                 case SEP_DASH:
7051                                         str = bytestring_to_str(NULL, bytes, fvalue_length(&fi->value), '-');
7052                                         break;
7053                                 case SEP_COLON:
7054                                         str = bytestring_to_str(NULL, bytes, fvalue_length(&fi->value), ':');
7055                                         break;
7056                                 case SEP_SPACE:
7057                                         str = bytestring_to_str(NULL, bytes, fvalue_length(&fi->value), ' ');
7058                                         break;
7059                                 case BASE_NONE:
7060                                 default:
7061                                         if (prefs.display_byte_fields_with_spaces)
7062                                         {
7063                                                 str = bytestring_to_str(NULL, bytes, fvalue_length(&fi->value), ' ');
7064                                         }
7065                                         else
7066                                         {
7067                                                 str = bytes_to_str(NULL, bytes, fvalue_length(&fi->value));
7068                                         }
7069                                         break;
7070                                 }
7071                                 label_fill(label_str, 0, hfinfo, str);
7072                                 wmem_free(NULL, str);
7073                         } else {
7074                                 if (hfinfo->display & BASE_ALLOW_ZERO) {
7075                                         label_fill(label_str, 0, hfinfo, "<none>");
7076                                 } else {
7077                                         label_fill(label_str, 0, hfinfo, "<MISSING>");
7078                                 }
7079                         }
7080                         break;
7081
7082                 /* Four types of integers to take care of:
7083                  *      Bitfield, with val_string
7084                  *      Bitfield, w/o val_string
7085                  *      Non-bitfield, with val_string
7086                  *      Non-bitfield, w/o val_string
7087                  */
7088                 case FT_UINT8:
7089                 case FT_UINT16:
7090                 case FT_UINT24:
7091                 case FT_UINT32:
7092                         if (hfinfo->bitmask) {
7093                                 fill_label_bitfield(fi, label_str, FALSE);
7094                         } else {
7095                                 fill_label_number(fi, label_str, FALSE);
7096                         }
7097                         break;
7098
7099                 case FT_FRAMENUM:
7100                         fill_label_number(fi, label_str, FALSE);
7101                         break;
7102
7103                 case FT_UINT40:
7104                 case FT_UINT48:
7105                 case FT_UINT56:
7106                 case FT_UINT64:
7107                         if (hfinfo->bitmask) {
7108                                 fill_label_bitfield64(fi, label_str, FALSE);
7109                         } else {
7110                                 fill_label_number64(fi, label_str, FALSE);
7111                         }
7112                         break;
7113
7114                 case FT_INT8:
7115                 case FT_INT16:
7116                 case FT_INT24:
7117                 case FT_INT32:
7118                         if (hfinfo->bitmask) {
7119                                 fill_label_bitfield(fi, label_str, TRUE);
7120                         } else {
7121                                 fill_label_number(fi, label_str, TRUE);
7122                         }
7123                         break;
7124
7125                 case FT_INT40:
7126                 case FT_INT48:
7127                 case FT_INT56:
7128                 case FT_INT64:
7129                         if (hfinfo->bitmask) {
7130                                 fill_label_bitfield64(fi, label_str, TRUE);
7131                         } else {
7132                                 fill_label_number64(fi, label_str, TRUE);
7133                         }
7134                         break;
7135
7136                 case FT_FLOAT:
7137                         g_snprintf(label_str, ITEM_LABEL_LENGTH,
7138                                    "%s: %." G_STRINGIFY(FLT_DIG) "g",
7139                                    hfinfo->name, fvalue_get_floating(&fi->value));
7140                         break;
7141
7142                 case FT_DOUBLE:
7143                         g_snprintf(label_str, ITEM_LABEL_LENGTH,
7144                                    "%s: %." G_STRINGIFY(DBL_DIG) "g",
7145                                    hfinfo->name, fvalue_get_floating(&fi->value));
7146                         break;
7147
7148                 case FT_ABSOLUTE_TIME:
7149                         tmp = abs_time_to_str(NULL, (const nstime_t *)fvalue_get(&fi->value), (absolute_time_display_e)hfinfo->display, TRUE);
7150                         label_fill(label_str, 0, hfinfo, tmp);
7151                         wmem_free(NULL, tmp);
7152                         break;
7153
7154                 case FT_RELATIVE_TIME:
7155                         tmp = rel_time_to_secs_str(NULL, (const nstime_t *)fvalue_get(&fi->value));
7156                         g_snprintf(label_str, ITEM_LABEL_LENGTH,
7157                                    "%s: %s seconds", hfinfo->name, tmp);
7158                         wmem_free(NULL, tmp);
7159                         break;
7160
7161                 case FT_IPXNET:
7162                         integer = fvalue_get_uinteger(&fi->value);
7163                         tmp = get_ipxnet_name(NULL, integer);
7164                         g_snprintf(label_str, ITEM_LABEL_LENGTH,
7165                                    "%s: %s (0x%08X)", hfinfo->name,
7166                                    tmp, integer);
7167                         wmem_free(NULL, tmp);
7168                         break;
7169
7170                 case FT_AX25:
7171                         addr.type = AT_AX25;
7172                         addr.len  = AX25_ADDR_LEN;
7173                         addr.data = (guint8 *)fvalue_get(&fi->value);
7174
7175                         addr_str = (char*)address_to_str(NULL, &addr);
7176                         g_snprintf(label_str, ITEM_LABEL_LENGTH,
7177                                    "%s: %s", hfinfo->name, addr_str);
7178                         wmem_free(NULL, addr_str);
7179                         break;
7180
7181                 case FT_VINES:
7182                         addr.type = vines_address_type;
7183                         addr.len  = VINES_ADDR_LEN;
7184                         addr.data = (guint8 *)fvalue_get(&fi->value);
7185
7186                         addr_str = (char*)address_to_str(NULL, &addr);
7187                         g_snprintf(label_str, ITEM_LABEL_LENGTH,
7188                                    "%s: %s", hfinfo->name, addr_str);
7189                         wmem_free(NULL, addr_str);
7190                         break;
7191
7192                 case FT_ETHER:
7193                         bytes = (guint8 *)fvalue_get(&fi->value);
7194
7195                         addr.type = AT_ETHER;
7196                         addr.len  = 6;
7197                         addr.data = bytes;
7198
7199                         addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
7200                         g_snprintf(label_str, ITEM_LABEL_LENGTH,
7201                                    "%s: %s", hfinfo->name, addr_str);
7202                         wmem_free(NULL, addr_str);
7203                         break;
7204
7205                 case FT_IPv4:
7206                         ipv4 = (ipv4_addr_and_mask *)fvalue_get(&fi->value);
7207                         n_addr = ipv4_get_net_order_addr(ipv4);
7208
7209                         addr.type = AT_IPv4;
7210                         addr.len  = 4;
7211                         addr.data = &n_addr;
7212
7213                         if (hfinfo->display == BASE_NETMASK)
7214                         {
7215                                 addr_str = (char*)address_to_str(NULL, &addr);
7216                         }
7217                         else
7218                         {
7219                                 addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
7220                         }
7221                         g_snprintf(label_str, ITEM_LABEL_LENGTH,
7222                                    "%s: %s", hfinfo->name, addr_str);
7223                         wmem_free(NULL, addr_str);
7224                         break;
7225
7226                 case FT_IPv6:
7227                         bytes = (guint8 *)fvalue_get(&fi->value);
7228
7229                         addr.type = AT_IPv6;
7230                         addr.len  = 16;
7231                         addr.data = bytes;
7232
7233                         addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
7234                         g_snprintf(label_str, ITEM_LABEL_LENGTH,
7235                                    "%s: %s", hfinfo->name, addr_str);
7236                         wmem_free(NULL, addr_str);
7237                         break;
7238
7239                 case FT_FCWWN:
7240                         addr.type = AT_FCWWN;
7241                         addr.len  = FCWWN_ADDR_LEN;
7242                         addr.data = (guint8 *)fvalue_get(&fi->value);
7243
7244                         addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
7245                         g_snprintf(label_str, ITEM_LABEL_LENGTH,
7246                                    "%s: %s", hfinfo->name, addr_str);
7247                         wmem_free(NULL, addr_str);
7248                         break;
7249
7250                 case FT_GUID:
7251                         guid = (e_guid_t *)fvalue_get(&fi->value);
7252                         tmp = guid_to_str(NULL, guid);
7253                         label_fill(label_str, 0, hfinfo, tmp);
7254                         wmem_free(NULL, tmp);
7255                         break;
7256
7257                 case FT_OID:
7258                         bytes = (guint8 *)fvalue_get(&fi->value);
7259                         name = oid_resolved_from_encoded(NULL, bytes, fvalue_length(&fi->value));
7260                         tmp = oid_encoded2string(NULL, bytes, fvalue_length(&fi->value));
7261                         if (name) {
7262                                 label_fill_descr(label_str, 0, hfinfo, tmp, name);
7263                                 wmem_free(NULL, name);
7264                         } else {
7265                                 label_fill(label_str, 0, hfinfo, tmp);
7266                         }
7267                         wmem_free(NULL, tmp);
7268                         break;
7269
7270                 case FT_REL_OID:
7271                         bytes = (guint8 *)fvalue_get(&fi->value);
7272                         name = rel_oid_resolved_from_encoded(NULL, bytes, fvalue_length(&fi->value));
7273                         tmp = rel_oid_encoded2string(NULL, bytes, fvalue_length(&fi->value));
7274                         if (name) {
7275                                 label_fill_descr(label_str, 0, hfinfo, tmp, name);
7276                                 wmem_free(NULL, name);
7277                         } else {
7278                                 label_fill(label_str, 0, hfinfo, tmp);
7279                         }
7280                         wmem_free(NULL, tmp);
7281                         break;
7282
7283                 case FT_SYSTEM_ID:
7284                         bytes = (guint8 *)fvalue_get(&fi->value);
7285                         tmp = print_system_id(NULL, bytes, fvalue_length(&fi->value));
7286                         label_fill(label_str, 0, hfinfo, tmp);
7287                         wmem_free(NULL, tmp);
7288                         break;
7289
7290                 case FT_EUI64:
7291                         integer64 = fvalue_get_uinteger64(&fi->value);
7292                         addr_str = eui64_to_str(NULL, integer64);
7293                         tmp = (char*)eui64_to_display(NULL, integer64);
7294                         label_fill_descr(label_str, 0, hfinfo, tmp, addr_str);
7295                         wmem_free(NULL, tmp);
7296                         wmem_free(NULL, addr_str);
7297                         break;
7298                 case FT_STRING:
7299                 case FT_STRINGZ:
7300                 case FT_UINT_STRING:
7301                 case FT_STRINGZPAD:
7302                         bytes = (guint8 *)fvalue_get(&fi->value);
7303                         label_fill(label_str, 0, hfinfo, hfinfo_format_text(hfinfo, bytes));
7304                         break;
7305
7306                 case FT_IEEE_11073_SFLOAT:
7307                         tmp = fvalue_to_string_repr(NULL, &fi->value, FTREPR_DISPLAY, hfinfo->display);
7308                         g_snprintf(label_str, ITEM_LABEL_LENGTH,
7309                                                 "%s: %s",
7310                                                 hfinfo->name, tmp);
7311                         wmem_free(NULL, tmp);
7312                         break;
7313                 case FT_IEEE_11073_FLOAT:
7314                         tmp = fvalue_to_string_repr(NULL, &fi->value, FTREPR_DISPLAY, hfinfo->display);
7315                         g_snprintf(label_str, ITEM_LABEL_LENGTH,
7316                                                 "%s: %s",
7317                                                 hfinfo->name, tmp);
7318                         wmem_free(NULL, tmp);
7319                         break;
7320
7321                 default:
7322                         g_error("hfinfo->type %d (%s) not handled\n",
7323                                 hfinfo->type, ftype_name(hfinfo->type));
7324                         DISSECTOR_ASSERT_NOT_REACHED();
7325                         break;
7326         }
7327 }
7328
7329 static void
7330 fill_label_boolean(field_info *fi, gchar *label_str)
7331 {
7332         char    *p                    = label_str;
7333         int      bitfield_byte_length = 0, bitwidth;
7334         guint64  unshifted_value;
7335         guint64  value;
7336
7337         header_field_info       *hfinfo   = fi->hfinfo;
7338         const true_false_string *tfstring = (const true_false_string *)&tfs_true_false;
7339
7340         if (hfinfo->strings) {
7341                 tfstring = (const struct true_false_string*) hfinfo->strings;
7342         }
7343
7344         value = fvalue_get_uinteger64(&fi->value);
7345         if (hfinfo->bitmask) {
7346                 /* Figure out the bit width */
7347                 bitwidth = hfinfo_container_bitwidth(hfinfo);
7348
7349                 /* Un-shift bits */
7350                 unshifted_value = value;
7351                 unshifted_value <<= hfinfo_bitshift(hfinfo);
7352
7353                 /* Create the bitfield first */
7354                 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
7355                 bitfield_byte_length = (int) (p - label_str);
7356         }
7357
7358         /* Fill in the textual info */
7359         label_fill(label_str, bitfield_byte_length, hfinfo, value ? tfstring->true_string : tfstring->false_string);
7360 }
7361
7362 static const char *
7363 hf_try_val_to_str(guint32 value, const header_field_info *hfinfo)
7364 {
7365         if (hfinfo->display & BASE_RANGE_STRING)
7366                 return try_rval_to_str(value, (const range_string *) hfinfo->strings);
7367
7368         if (hfinfo->display & BASE_EXT_STRING)
7369                 return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
7370
7371         if (hfinfo->display & BASE_VAL64_STRING)
7372                 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
7373
7374         return try_val_to_str(value, (const value_string *) hfinfo->strings);
7375 }
7376
7377 static const char *
7378 hf_try_val64_to_str(guint64 value, const header_field_info *hfinfo)
7379 {
7380         if (hfinfo->display & BASE_VAL64_STRING)
7381                 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
7382
7383         /* If this is reached somebody registered a 64-bit field with a 32-bit
7384          * value-string, which isn't right. */
7385         DISSECTOR_ASSERT_NOT_REACHED();
7386
7387         /* This is necessary to squelch MSVC errors; is there
7388            any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
7389            never returns? */
7390         return NULL;
7391 }
7392
7393 static const char *
7394 hf_try_val_to_str_const(guint32 value, const header_field_info *hfinfo, const char *unknown_str)
7395 {
7396         const char *str = hf_try_val_to_str(value, hfinfo);
7397
7398         return (str) ? str : unknown_str;
7399 }
7400
7401 static const char *
7402 hf_try_val64_to_str_const(guint64 value, const header_field_info *hfinfo, const char *unknown_str)
7403 {
7404         const char *str = hf_try_val64_to_str(value, hfinfo);
7405
7406         return (str) ? str : unknown_str;
7407 }
7408
7409 /* Fills data for bitfield ints with val_strings */
7410 static void
7411 fill_label_bitfield(field_info *fi, gchar *label_str, gboolean is_signed)
7412 {
7413         char       *p;
7414         int         bitfield_byte_length, bitwidth;
7415         guint32     unshifted_value;
7416         guint32     value;
7417
7418         char        buf[32];
7419         const char *out;
7420
7421         header_field_info *hfinfo = fi->hfinfo;
7422
7423         /* Figure out the bit width */
7424         bitwidth = hfinfo_container_bitwidth(hfinfo);
7425
7426         /* Un-shift bits */
7427         if (is_signed)
7428                 value = fvalue_get_sinteger(&fi->value);
7429         else
7430                 value = fvalue_get_uinteger(&fi->value);
7431
7432         unshifted_value = value;
7433         if (hfinfo->bitmask) {
7434                 unshifted_value <<= hfinfo_bitshift(hfinfo);
7435         }
7436
7437         /* Create the bitfield first */
7438         p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
7439         bitfield_byte_length = (int) (p - label_str);
7440
7441         /* Fill in the textual info using stored (shifted) value */
7442         if (hfinfo->display == BASE_CUSTOM) {
7443                 gchar tmp[ITEM_LABEL_LENGTH];
7444                 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
7445
7446                 DISSECTOR_ASSERT(fmtfunc);
7447                 fmtfunc(tmp, value);
7448                 label_fill(label_str, bitfield_byte_length, hfinfo, tmp);
7449         }
7450         else if (hfinfo->strings) {
7451                 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
7452
7453                 out = hfinfo_number_vals_format(hfinfo, buf, value);
7454                 if (out == NULL) /* BASE_NONE so don't put integer in descr */
7455                         label_fill(label_str, bitfield_byte_length, hfinfo, val_str);
7456                 else
7457                         label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out);
7458         }
7459         else {
7460                 out = hfinfo_number_value_format(hfinfo, buf, value);
7461
7462                 label_fill(label_str, bitfield_byte_length, hfinfo, out);
7463         }
7464 }
7465
7466 static void
7467 fill_label_bitfield64(field_info *fi, gchar *label_str, gboolean is_signed)
7468 {
7469         char       *p;
7470         int         bitfield_byte_length, bitwidth;
7471         guint64     unshifted_value;
7472         guint64     value;
7473
7474         char        buf[48];
7475         const char *out;
7476
7477         header_field_info *hfinfo = fi->hfinfo;
7478
7479         /* Figure out the bit width */
7480         bitwidth = hfinfo_container_bitwidth(hfinfo);
7481
7482         /* Un-shift bits */
7483         if (is_signed)
7484                 value = fvalue_get_sinteger64(&fi->value);
7485         else
7486                 value = fvalue_get_uinteger64(&fi->value);
7487
7488         unshifted_value = value;
7489         if (hfinfo->bitmask) {
7490                 unshifted_value <<= hfinfo_bitshift(hfinfo);
7491         }
7492
7493         /* Create the bitfield first */
7494         p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
7495         bitfield_byte_length = (int) (p - label_str);
7496
7497         /* Fill in the textual info using stored (shifted) value */
7498         if (hfinfo->display == BASE_CUSTOM) {
7499                 gchar tmp[ITEM_LABEL_LENGTH];
7500                 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
7501
7502                 DISSECTOR_ASSERT(fmtfunc64);
7503                 fmtfunc64(tmp, value);
7504                 label_fill(label_str, bitfield_byte_length, hfinfo, tmp);
7505         }
7506         else if (hfinfo->strings) {
7507                 const char *val_str = hf_try_val64_to_str_const(value, hfinfo, "Unknown");
7508
7509                 out = hfinfo_number_vals_format64(hfinfo, buf, value);
7510                 if (out == NULL) /* BASE_NONE so don't put integer in descr */
7511                         label_fill(label_str, bitfield_byte_length, hfinfo, val_str);
7512                 else
7513                         label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out);
7514         }
7515         else {
7516                 out = hfinfo_number_value_format64(hfinfo, buf, value);
7517
7518                 label_fill(label_str, bitfield_byte_length, hfinfo, out);
7519         }
7520 }
7521
7522 static void
7523 fill_label_number(field_info *fi, gchar *label_str, gboolean is_signed)
7524 {
7525         header_field_info *hfinfo = fi->hfinfo;
7526         guint32            value;
7527
7528         char               buf[32];
7529         const char        *out;
7530
7531         if (is_signed)
7532                 value = fvalue_get_sinteger(&fi->value);
7533         else
7534                 value = fvalue_get_uinteger(&fi->value);
7535
7536         /* Fill in the textual info */
7537         if (hfinfo->display == BASE_CUSTOM) {
7538                 gchar tmp[ITEM_LABEL_LENGTH];
7539                 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
7540
7541                 DISSECTOR_ASSERT(fmtfunc);
7542                 fmtfunc(tmp, value);
7543                 label_fill(label_str, 0, hfinfo, tmp);
7544         }
7545         else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) { /* Add fill_label_framenum? */
7546                 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
7547
7548                 out = hfinfo_number_vals_format(hfinfo, buf, value);
7549                 if (out == NULL) /* BASE_NONE so don't put integer in descr */
7550                         label_fill(label_str, 0, hfinfo, val_str);
7551                 else
7552                         label_fill_descr(label_str, 0, hfinfo, val_str, out);
7553         }
7554         else if (IS_BASE_PORT(hfinfo->display)) {
7555                 gchar tmp[ITEM_LABEL_LENGTH];
7556
7557                 port_with_resolution_to_str_buf(tmp, sizeof(tmp),
7558                         display_to_port_type((field_display_e)hfinfo->display), value);
7559                 label_fill(label_str, 0, hfinfo, tmp);
7560         }
7561         else {
7562                 out = hfinfo_number_value_format(hfinfo, buf, value);
7563
7564                 label_fill(label_str, 0, hfinfo, out);
7565         }
7566 }
7567
7568 static void
7569 fill_label_number64(field_info *fi, gchar *label_str, gboolean is_signed)
7570 {
7571         header_field_info *hfinfo = fi->hfinfo;
7572         guint64            value;
7573
7574         char               buf[48];
7575         const char        *out;
7576
7577         if (is_signed)
7578                 value = fvalue_get_sinteger64(&fi->value);
7579         else
7580                 value = fvalue_get_uinteger64(&fi->value);
7581
7582         /* Fill in the textual info */
7583         if (hfinfo->display == BASE_CUSTOM) {
7584                 gchar tmp[ITEM_LABEL_LENGTH];
7585                 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
7586
7587                 DISSECTOR_ASSERT(fmtfunc64);
7588                 fmtfunc64(tmp, value);
7589                 label_fill(label_str, 0, hfinfo, tmp);
7590         }
7591         else if (hfinfo->strings) {
7592                 const char *val_str = hf_try_val64_to_str_const(value, hfinfo, "Unknown");
7593
7594                 out = hfinfo_number_vals_format64(hfinfo, buf, value);
7595                 if (out == NULL) /* BASE_NONE so don't put integer in descr */
7596                         label_fill(label_str, 0, hfinfo, val_str);
7597                 else
7598                         label_fill_descr(label_str, 0, hfinfo, val_str, out);
7599         }
7600         else {
7601                 out = hfinfo_number_value_format64(hfinfo, buf, value);
7602
7603                 label_fill(label_str, 0, hfinfo, out);
7604         }
7605 }
7606
7607 int
7608 hfinfo_bitshift(const header_field_info *hfinfo)
7609 {
7610         return ws_ctz(hfinfo->bitmask);
7611 }
7612
7613 static int
7614 hfinfo_mask_bitwidth(const header_field_info *hfinfo)
7615 {
7616         if (!hfinfo->bitmask) {
7617                 return 0;
7618         }
7619
7620         /* ilog2 = first set bit, ctz = last set bit */
7621         return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
7622 }
7623
7624 static int
7625 hfinfo_type_bitwidth(enum ftenum type)
7626 {
7627         int bitwidth = 0;
7628
7629         switch (type) {
7630                 case FT_UINT8:
7631                 case FT_INT8:
7632                         bitwidth = 8;
7633                         break;
7634                 case FT_UINT16:
7635                 case FT_INT16:
7636                         bitwidth = 16;
7637                         break;
7638                 case FT_UINT24:
7639                 case FT_INT24:
7640                         bitwidth = 24;
7641                         break;
7642                 case FT_UINT32:
7643                 case FT_INT32:
7644                         bitwidth = 32;
7645                         break;
7646                 case FT_UINT40:
7647                 case FT_INT40:
7648                         bitwidth = 40;
7649                         break;
7650                 case FT_UINT48:
7651                 case FT_INT48:
7652                         bitwidth = 48;
7653                         break;
7654                 case FT_UINT56:
7655                 case FT_INT56:
7656                         bitwidth = 56;
7657                         break;
7658                 case FT_UINT64:
7659                 case FT_INT64:
7660                         bitwidth = 64;
7661                         break;
7662                 default:
7663                         DISSECTOR_ASSERT_NOT_REACHED();
7664                         ;
7665         }
7666         return bitwidth;
7667 }
7668
7669
7670 static int
7671 hfinfo_container_bitwidth(const header_field_info *hfinfo)
7672 {
7673         if (!hfinfo->bitmask) {
7674                 return 0;
7675         }
7676
7677         if (hfinfo->type == FT_BOOLEAN) {
7678                 return hfinfo->display; /* hacky? :) */
7679         }
7680
7681         return hfinfo_type_bitwidth(hfinfo->type);
7682 }
7683
7684 static int
7685 hfinfo_hex_digits(const header_field_info *hfinfo)
7686 {
7687         int bitwidth;
7688
7689         /* If we have a bitmask, hfinfo->type is the width of the container, so not
7690          * appropriate to determine the number of hex digits for the field.
7691          * So instead, we compute it from the bitmask.
7692          */
7693         if (hfinfo->bitmask != 0) {
7694                 bitwidth = hfinfo_mask_bitwidth(hfinfo);
7695         } else {
7696                 bitwidth = hfinfo_type_bitwidth(hfinfo->type);
7697         }
7698
7699         /* Divide by 4, rounding up, to get number of hex digits. */
7700         return (bitwidth + 3) / 4;
7701 }
7702
7703 static const char *
7704 hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[32], guint32 value)
7705 {
7706         char *ptr = &buf[31];
7707         gboolean isint = IS_FT_INT(hfinfo->type);
7708
7709         *ptr = '\0';
7710         /* Properly format value */
7711         switch (display & FIELD_DISPLAY_E_MASK) {
7712                 case BASE_DEC:
7713                         return isint ? int_to_str_back(ptr, (gint32) value) : uint_to_str_back(ptr, value);
7714
7715                 case BASE_DEC_HEX:
7716                         *(--ptr) = ')';
7717                         ptr = hex_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
7718                         *(--ptr) = '(';
7719                         *(--ptr) = ' ';
7720                         ptr = isint ? int_to_str_back(ptr, (gint32) value) : uint_to_str_back(ptr, value);
7721                         return ptr;
7722
7723                 case BASE_OCT:
7724                         return oct_to_str_back(ptr, value);
7725
7726                 case BASE_HEX:
7727                         return hex_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
7728
7729                 case BASE_HEX_DEC:
7730                         *(--ptr) = ')';
7731                         ptr = isint ? int_to_str_back(ptr, (gint32) value) : uint_to_str_back(ptr, value);
7732                         *(--ptr) = '(';
7733                         *(--ptr) = ' ';
7734                         ptr = hex_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
7735                         return ptr;
7736
7737                 case BASE_PT_UDP:
7738                 case BASE_PT_TCP:
7739                 case BASE_PT_DCCP:
7740                 case BASE_PT_SCTP:
7741                         port_with_resolution_to_str_buf(buf, 32,
7742                                         display_to_port_type((field_display_e)display), value);
7743                         return buf;
7744
7745                 default:
7746                         g_assert_not_reached();
7747         }
7748         return ptr;
7749 }
7750
7751 static const char *
7752 hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[48], guint64 value)
7753 {
7754         char *ptr = &buf[47];
7755         gboolean isint = IS_FT_INT(hfinfo->type);
7756
7757         *ptr = '\0';
7758         /* Properly format value */
7759                 switch (display) {
7760                         case BASE_DEC:
7761                                 return isint ? int64_to_str_back(ptr, (gint64) value) : uint64_to_str_back(ptr, value);
7762
7763                         case BASE_DEC_HEX:
7764                                 *(--ptr) = ')';
7765                                 ptr = hex64_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
7766                                 *(--ptr) = '(';
7767                                 *(--ptr) = ' ';
7768                                 ptr = isint ? int64_to_str_back(ptr, (gint64) value) : uint64_to_str_back(ptr, value);
7769                                 return ptr;
7770
7771                         case BASE_OCT:
7772                                 return oct64_to_str_back(ptr, value);
7773
7774                         case BASE_HEX:
7775                                 return hex64_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
7776
7777                         case BASE_HEX_DEC:
7778                                 *(--ptr) = ')';
7779                                 ptr = isint ? int64_to_str_back(ptr, (gint64) value) : uint64_to_str_back(ptr, value);
7780                                 *(--ptr) = '(';
7781                                 *(--ptr) = ' ';
7782                                 ptr = hex64_to_str_back(ptr, hfinfo_hex_digits(hfinfo), value);
7783                                 return ptr;
7784
7785                         default:
7786                                 g_assert_not_reached();
7787                 }
7788         return ptr;
7789 }
7790
7791 static const char *
7792 hfinfo_number_value_format(const header_field_info *hfinfo, char buf[32], guint32 value)
7793 {
7794         int display = hfinfo->display;
7795
7796         if (hfinfo->type == FT_FRAMENUM) {
7797                 /*
7798                  * Frame numbers are always displayed in decimal.
7799                  */
7800                 display = BASE_DEC;
7801         }
7802
7803         return hfinfo_number_value_format_display(hfinfo, display, buf, value);
7804 }
7805
7806 static const char *
7807 hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[64], guint64 value)
7808 {
7809         int display = hfinfo->display;
7810
7811         if (hfinfo->type == FT_FRAMENUM) {
7812                 /*
7813                  * Frame numbers are always displayed in decimal.
7814                  */
7815                 display = BASE_DEC;
7816         }
7817
7818         return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
7819 }
7820
7821 static const char *
7822 hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[32], guint32 value)
7823 {
7824         /* Get the underlying BASE_ value */
7825         int display = hfinfo->display & FIELD_DISPLAY_E_MASK;
7826
7827         if (hfinfo->type == FT_FRAMENUM) {
7828                 /*
7829                  * Frame numbers are always displayed in decimal.
7830                  */
7831                 display = BASE_DEC;
7832         }
7833
7834         if (IS_BASE_PORT(display)) {
7835                 display = BASE_DEC;
7836         }
7837
7838         switch (display) {
7839                 case BASE_NONE:
7840                 /* case BASE_DEC: */
7841                 case BASE_DEC_HEX:
7842                 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
7843                 case BASE_CUSTOM:
7844                         display = BASE_DEC;
7845                         break;
7846
7847                 /* case BASE_HEX: */
7848                 case BASE_HEX_DEC:
7849                         display = BASE_HEX;
7850                         break;
7851         }
7852
7853         return hfinfo_number_value_format_display(hfinfo, display, buf, value);
7854 }
7855
7856 static const char *
7857 hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[64], guint64 value)
7858 {
7859         /* Get the underlying BASE_ value */
7860         int display = hfinfo->display & FIELD_DISPLAY_E_MASK;
7861
7862         if (hfinfo->type == FT_FRAMENUM) {
7863                 /*
7864                  * Frame numbers are always displayed in decimal.
7865                  */
7866                 display = BASE_DEC;
7867         }
7868
7869         switch (display) {
7870                 case BASE_NONE:
7871                 /* case BASE_DEC: */
7872                 case BASE_DEC_HEX:
7873                 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
7874                 case BASE_CUSTOM:
7875                         display = BASE_DEC;
7876                         break;
7877
7878                 /* case BASE_HEX: */
7879                 case BASE_HEX_DEC:
7880                         display = BASE_HEX;
7881                         break;
7882         }
7883
7884         return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
7885 }
7886
7887 static const char *
7888 hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value)
7889 {
7890         /* Get the underlying BASE_ value */
7891         int display = hfinfo->display & FIELD_DISPLAY_E_MASK;
7892
7893         if (display == BASE_NONE)
7894                 return NULL;
7895
7896         if (display == BASE_DEC_HEX)
7897                 display = BASE_DEC;
7898         if (display == BASE_HEX_DEC)
7899                 display = BASE_HEX;
7900
7901         return hfinfo_number_value_format_display(hfinfo, display, buf, value);
7902 }
7903
7904 static const char *
7905 hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[64], guint64 value)
7906 {
7907         /* Get the underlying BASE_ value */
7908         int display = hfinfo->display & FIELD_DISPLAY_E_MASK;
7909
7910         if (display == BASE_NONE)
7911                 return NULL;
7912
7913         if (display == BASE_DEC_HEX)
7914                 display = BASE_DEC;
7915         if (display == BASE_HEX_DEC)
7916                 display = BASE_HEX;
7917
7918         return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
7919 }
7920
7921 const char *
7922 proto_registrar_get_name(const int n)
7923 {
7924         header_field_info *hfinfo;
7925
7926         PROTO_REGISTRAR_GET_NTH(n, hfinfo);
7927         return hfinfo->name;
7928 }
7929
7930 const char *
7931 proto_registrar_get_abbrev(const int n)
7932 {
7933         header_field_info *hfinfo;
7934
7935         PROTO_REGISTRAR_GET_NTH(n, hfinfo);
7936         return hfinfo->abbrev;
7937 }
7938
7939 enum ftenum
7940 proto_registrar_get_ftype(const int n)
7941 {
7942         header_field_info *hfinfo;
7943
7944         PROTO_REGISTRAR_GET_NTH(n, hfinfo);
7945         return hfinfo->type;
7946 }
7947
7948 int
7949 proto_registrar_get_parent(const int n)
7950 {
7951         header_field_info *hfinfo;
7952
7953         PROTO_REGISTRAR_GET_NTH(n, hfinfo);
7954         return hfinfo->parent;
7955 }
7956
7957 gboolean
7958 proto_registrar_is_protocol(const int n)
7959 {
7960         header_field_info *hfinfo;
7961
7962         PROTO_REGISTRAR_GET_NTH(n, hfinfo);
7963         return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? TRUE : FALSE);
7964 }
7965
7966 /* Returns length of field in packet (not necessarily the length
7967  * in our internal representation, as in the case of IPv4).
7968  * 0 means undeterminable at time of registration
7969  * -1 means the field is not registered. */
7970 gint
7971 proto_registrar_get_length(const int n)
7972 {
7973         header_field_info *hfinfo;
7974
7975         PROTO_REGISTRAR_GET_NTH(n, hfinfo);
7976         return ftype_length(hfinfo->type);
7977 }
7978
7979 /* Looks for a protocol or a field in a proto_tree. Returns TRUE if
7980  * it exists anywhere, or FALSE if it exists nowhere. */
7981 gboolean
7982 proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
7983 {
7984         GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
7985
7986         if (g_ptr_array_len(ptrs) > 0) {
7987                 return TRUE;
7988         }
7989         else {
7990                 return FALSE;
7991         }
7992 }
7993
7994 /* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
7995  * This only works if the hfindex was "primed" before the dissection
7996  * took place, as we just pass back the already-created GPtrArray*.
7997  * The caller should *not* free the GPtrArray*; proto_tree_free_node()
7998  * handles that. */
7999 GPtrArray *
8000 proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
8001 {
8002         if (!tree)
8003                 return NULL;
8004
8005         if (PTREE_DATA(tree)->interesting_hfids != NULL)
8006                 return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)->interesting_hfids,
8007                                            GINT_TO_POINTER(id));
8008         else
8009                 return NULL;
8010 }
8011
8012 gboolean
8013 proto_tracking_interesting_fields(const proto_tree *tree)
8014 {
8015         GHashTable *interesting_hfids;
8016
8017         if (!tree)
8018                 return FALSE;
8019
8020         interesting_hfids = PTREE_DATA(tree)->interesting_hfids;
8021
8022         return (interesting_hfids != NULL) && g_hash_table_size(interesting_hfids);
8023 }
8024
8025 /* Helper struct for proto_find_info() and      proto_all_finfos() */
8026 typedef struct {
8027         GPtrArray *array;
8028         int        id;
8029 } ffdata_t;
8030
8031 /* Helper function for proto_find_info() */
8032 static gboolean
8033 find_finfo(proto_node *node, gpointer data)
8034 {
8035         field_info *fi = PNODE_FINFO(node);
8036         if (fi && fi->hfinfo) {
8037                 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
8038                         g_ptr_array_add(((ffdata_t*)data)->array, fi);
8039                 }
8040         }
8041
8042         /* Don't stop traversing. */
8043         return FALSE;
8044 }
8045
8046 /* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
8047 * This works on any proto_tree, primed or unprimed, but actually searches
8048 * the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
8049 * The caller does need to free the returned GPtrArray with
8050 * g_ptr_array_free(<array>, TRUE).
8051 */
8052 GPtrArray *
8053 proto_find_finfo(proto_tree *tree, const int id)
8054 {
8055         ffdata_t ffdata;
8056
8057         ffdata.array = g_ptr_array_new();
8058         ffdata.id = id;
8059
8060         proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
8061
8062         return ffdata.array;
8063 }
8064
8065 /* Helper function for proto_all_finfos() */
8066 static gboolean
8067 every_finfo(proto_node *node, gpointer data)
8068 {
8069         field_info *fi = PNODE_FINFO(node);
8070         if (fi && fi->hfinfo) {
8071                 g_ptr_array_add(((ffdata_t*)data)->array, fi);
8072         }
8073
8074         /* Don't stop traversing. */
8075         return FALSE;
8076 }
8077
8078 /* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree. */
8079 GPtrArray *
8080 proto_all_finfos(proto_tree *tree)
8081 {
8082         ffdata_t ffdata;
8083
8084         ffdata.array = g_ptr_array_new();
8085         ffdata.id = 0;
8086
8087         proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
8088
8089         return ffdata.array;
8090 }
8091
8092
8093 typedef struct {
8094         guint       offset;
8095         field_info *finfo;
8096         tvbuff_t   *tvb;
8097 } offset_search_t;
8098
8099 static gboolean
8100 check_for_offset(proto_node *node, gpointer data)
8101 {
8102         field_info      *fi        = PNODE_FINFO(node);
8103         offset_search_t *offsearch = (offset_search_t *)data;
8104
8105         /* !fi == the top most container node which holds nothing */
8106         if (fi && !PROTO_ITEM_IS_HIDDEN(node) && !PROTO_ITEM_IS_GENERATED(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
8107                 if (offsearch->offset >= (guint) fi->start &&
8108                                 offsearch->offset < (guint) (fi->start + fi->length)) {
8109
8110                         offsearch->finfo = fi;
8111                         return FALSE; /* keep traversing */
8112                 }
8113         }
8114         return FALSE; /* keep traversing */
8115 }
8116
8117 /* Search a proto_tree backwards (from leaves to root) looking for the field
8118  * whose start/length occupies 'offset' */
8119 /* XXX - I couldn't find an easy way to search backwards, so I search
8120  * forwards, w/o stopping. Therefore, the last finfo I find will the be
8121  * the one I want to return to the user. This algorithm is inefficient
8122  * and could be re-done, but I'd have to handle all the children and
8123  * siblings of each node myself. When I have more time I'll do that.
8124  * (yeah right) */
8125 field_info *
8126 proto_find_field_from_offset(proto_tree *tree, guint offset, tvbuff_t *tvb)
8127 {
8128         offset_search_t offsearch;
8129
8130         offsearch.offset = offset;
8131         offsearch.finfo  = NULL;
8132         offsearch.tvb    = tvb;
8133
8134         proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
8135
8136         return offsearch.finfo;
8137 }
8138
8139
8140 static gboolean
8141 check_for_undecoded(proto_node *node, gpointer data)
8142 {
8143         field_info *fi = PNODE_FINFO(node);
8144         gchar* decoded = (gchar*)data;
8145         gint i;
8146         guint byte;
8147         guint bit;
8148
8149         if (fi && fi->hfinfo->type != FT_PROTOCOL) {
8150                 for (i = fi->start; i < fi->start + fi->length; i++) {
8151                         byte = i / 8;
8152                         bit = i % 8;
8153                         decoded[byte] |= (1 << bit);
8154                 }
8155         }
8156
8157         return FALSE;
8158 }
8159
8160 gchar*
8161 proto_find_undecoded_data(proto_tree *tree, guint length)
8162 {
8163         gchar* decoded = (gchar*)wmem_alloc0(wmem_packet_scope(), length / 8 + 1);
8164
8165         proto_tree_traverse_pre_order(tree, check_for_undecoded, decoded);
8166         return decoded;
8167 }
8168
8169 /* Dumps the protocols in the registration database to stdout.  An independent
8170  * program can take this output and format it into nice tables or HTML or
8171  * whatever.
8172  *
8173  * There is one record per line. The fields are tab-delimited.
8174  *
8175  * Field 1 = protocol name
8176  * Field 2 = protocol short name
8177  * Field 3 = protocol filter name
8178  */
8179 void
8180 proto_registrar_dump_protocols(void)
8181 {
8182         protocol_t *protocol;
8183         int         i;
8184         void       *cookie = NULL;
8185
8186
8187         i = proto_get_first_protocol(&cookie);
8188         while (i != -1) {
8189                 protocol = find_protocol_by_id(i);
8190                 printf("%s\t%s\t%s\n", protocol->name, protocol->short_name,
8191                         protocol->filter_name);
8192                 i = proto_get_next_protocol(&cookie);
8193         }
8194 }
8195
8196 /* Dumps the value_strings, extended value string headers, range_strings
8197  * or true/false strings for fields that have them.
8198  * There is one record per line. Fields are tab-delimited.
8199  * There are four types of records: Value String, Extended Value String Header,
8200  * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
8201  * the type of record.
8202  *
8203  * Note that a record will be generated only if the value_string,... is referenced
8204  * in a registered hfinfo entry.
8205  *
8206  *
8207  * Value Strings
8208  * -------------
8209  * Field 1 = 'V'
8210  * Field 2 = Field abbreviation to which this value string corresponds
8211  * Field 3 = Integer value
8212  * Field 4 = String
8213  *
8214  * Extended Value String Headers
8215  * -----------------------------
8216  * Field 1 = 'E'
8217  * Field 2 = Field abbreviation to which this extended value string header corresponds
8218  * Field 3 = Extended Value String "Name"
8219  * Field 4 = Number of entries in the associated value_string array
8220  * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
8221  *
8222  * Range Strings
8223  * -------------
8224  * Field 1 = 'R'
8225  * Field 2 = Field abbreviation to which this range string corresponds
8226  * Field 3 = Integer value: lower bound
8227  * Field 4 = Integer value: upper bound
8228  * Field 5 = String
8229  *
8230  * True/False Strings
8231  * ------------------
8232  * Field 1 = 'T'
8233  * Field 2 = Field abbreviation to which this true/false string corresponds
8234  * Field 3 = True String
8235  * Field 4 = False String
8236  */
8237 void
8238 proto_registrar_dump_values(void)
8239 {
8240         header_field_info       *hfinfo;
8241         int                     i, len, vi;
8242         const value_string      *vals;
8243         const val64_string      *vals64;
8244         const range_string      *range;
8245         const true_false_string *tfs;
8246
8247         len = gpa_hfinfo.len;
8248         for (i = 0; i < len ; i++) {
8249                 if (gpa_hfinfo.hfi[i] == NULL)
8250                         continue; /* This is a deregistered protocol or field */
8251
8252                 PROTO_REGISTRAR_GET_NTH(i, hfinfo);
8253
8254                  if (hfinfo->id == hf_text_only) {
8255                          continue;
8256                  }
8257
8258                 /* ignore protocols */
8259                 if (proto_registrar_is_protocol(i)) {
8260                         continue;
8261                 }
8262                 /* process header fields */
8263 #if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
8264                 /*
8265                  * If this field isn't at the head of the list of
8266                  * fields with this name, skip this field - all
8267                  * fields with the same name are really just versions
8268                  * of the same field stored in different bits, and
8269                  * should have the same type/radix/value list, and
8270                  * just differ in their bit masks.      (If a field isn't
8271                  * a bitfield, but can be, say, 1 or 2 bytes long,
8272                  * it can just be made FT_UINT16, meaning the
8273                  * *maximum* length is 2 bytes, and be used
8274                  * for all lengths.)
8275                  */
8276                 if (hfinfo->same_name_prev_id != -1)
8277                         continue;
8278 #endif
8279                 vals   = NULL;
8280                 vals64 = NULL;
8281                 range  = NULL;
8282                 tfs    = NULL;
8283
8284                 if (hfinfo->strings != NULL) {
8285                         if ((hfinfo->display & FIELD_DISPLAY_E_MASK) != BASE_CUSTOM &&
8286                             (hfinfo->type == FT_UINT8  ||
8287                              hfinfo->type == FT_UINT16 ||
8288                              hfinfo->type == FT_UINT24 ||
8289                              hfinfo->type == FT_UINT32 ||
8290                              hfinfo->type == FT_UINT40 ||
8291                              hfinfo->type == FT_UINT48 ||
8292                              hfinfo->type == FT_UINT56 ||
8293                              hfinfo->type == FT_UINT64 ||
8294                              hfinfo->type == FT_INT8   ||
8295                              hfinfo->type == FT_INT16  ||
8296                              hfinfo->type == FT_INT24  ||
8297                              hfinfo->type == FT_INT32  ||
8298                              hfinfo->type == FT_INT40  ||
8299                              hfinfo->type == FT_INT48  ||
8300                              hfinfo->type == FT_INT56  ||
8301                              hfinfo->type == FT_INT64)) {
8302
8303                                 if (hfinfo->display & BASE_RANGE_STRING) {
8304                                         range = (const range_string *)hfinfo->strings;
8305                                 } else if (hfinfo->display & BASE_EXT_STRING) {
8306                                         vals = VALUE_STRING_EXT_VS_P((value_string_ext *)hfinfo->strings);
8307                                 } else if (hfinfo->display & BASE_VAL64_STRING) {
8308                                         vals64 = (const val64_string *)hfinfo->strings;
8309                                 } else {
8310                                         vals = (const value_string *)hfinfo->strings;
8311                                 }
8312                         }
8313                         else if (hfinfo->type == FT_BOOLEAN) {
8314                                 tfs = (const struct true_false_string *)hfinfo->strings;
8315                         }
8316                 }
8317
8318                 /* Print value strings? */
8319                 if (vals) {
8320                         if (hfinfo->display & BASE_EXT_STRING) {
8321                                 value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
8322                                 if (!value_string_ext_validate(vse_p)) {
8323                                         g_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev);
8324                                         continue;
8325                                 }
8326                                 try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
8327                                 printf("E\t%s\t%u\t%s\t%s\n",
8328                                        hfinfo->abbrev,
8329                                        VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p),
8330                                        VALUE_STRING_EXT_VS_NAME(vse_p),
8331                                        value_string_ext_match_type_str(vse_p));
8332                         }
8333                         vi = 0;
8334                         while (vals[vi].strptr) {
8335                                 /* Print in the proper base */
8336                                 if (hfinfo->display == BASE_HEX) {
8337                                         printf("V\t%s\t0x%x\t%s\n",
8338                                                hfinfo->abbrev,
8339                                                vals[vi].value,
8340                                                vals[vi].strptr);
8341                                 }
8342                                 else {
8343                                         printf("V\t%s\t%u\t%s\n",
8344                                                hfinfo->abbrev,
8345                                                vals[vi].value,
8346                                                vals[vi].strptr);
8347                                 }
8348                                 vi++;
8349                         }
8350                 }
8351                 else if (vals64) {
8352                         vi = 0;
8353                         while (vals64[vi].strptr) {
8354                                 printf("V64\t%s\t%" G_GINT64_MODIFIER "u\t%s\n",
8355                                        hfinfo->abbrev,
8356                                        vals64[vi].value,
8357                                        vals64[vi].strptr);
8358                                 vi++;
8359                         }
8360                 }
8361
8362                 /* print range strings? */
8363                 else if (range) {
8364                         vi = 0;
8365                         while (range[vi].strptr) {
8366                                 /* Print in the proper base */
8367                                 if ((hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_HEX) {
8368                                         printf("R\t%s\t0x%x\t0x%x\t%s\n",
8369                                                hfinfo->abbrev,
8370                                                range[vi].value_min,
8371                                                range[vi].value_max,
8372                                                range[vi].strptr);
8373                                 }
8374                                 else {
8375                                         printf("R\t%s\t%u\t%u\t%s\n",
8376                                                hfinfo->abbrev,
8377                                                range[vi].value_min,
8378                                                range[vi].value_max,
8379                                                range[vi].strptr);
8380                                 }
8381                                 vi++;
8382                         }
8383                 }
8384
8385                 /* Print true/false strings? */
8386                 else if (tfs) {
8387                         printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
8388                                tfs->true_string, tfs->false_string);
8389                 }
8390         }
8391 }
8392
8393 /* Prints the number of registered fields.
8394  * Useful for determining an appropriate value for
8395  * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
8396  *
8397  * Returns FALSE if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
8398  * the number of fields, TRUE otherwise.
8399  */
8400 gboolean
8401 proto_registrar_dump_fieldcount(void)
8402 {
8403         guint32                 i;
8404         header_field_info       *hfinfo;
8405         guint32                 deregistered_count = 0;
8406         guint32                 same_name_count = 0;
8407         guint32                 protocol_count = 0;
8408
8409         for (i = 0; i < gpa_hfinfo.len; i++) {
8410                 if (gpa_hfinfo.hfi[i] == NULL) {
8411                         deregistered_count++;
8412                         continue; /* This is a deregistered protocol or header field */
8413                 }
8414
8415                 PROTO_REGISTRAR_GET_NTH(i, hfinfo);
8416
8417                 if (proto_registrar_is_protocol(i))
8418                         protocol_count++;
8419
8420                 if (hfinfo->same_name_prev_id != -1)
8421                         same_name_count++;
8422         }
8423
8424         printf ("There are %u header fields registered, of which:\n"
8425                 "\t%u are deregistered\n"
8426                 "\t%u are protocols\n"
8427                 "\t%u have the same name as another field\n\n",
8428                 gpa_hfinfo.len, deregistered_count, protocol_count,
8429                 same_name_count);
8430
8431         printf ("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM,
8432                 (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM) ?
8433                     "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
8434                     "\n");
8435
8436         printf ("The header field table consumes %u KiB of memory.\n",
8437                 (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
8438         printf ("The fields themselves consume %u KiB of memory.\n",
8439                 (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
8440
8441         return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM);
8442 }
8443
8444
8445 /* Dumps the contents of the registration database to stdout. An independent
8446  * program can take this output and format it into nice tables or HTML or
8447  * whatever.
8448  *
8449  * There is one record per line. Each record is either a protocol or a header
8450  * field, differentiated by the first field. The fields are tab-delimited.
8451  *
8452  * Protocols
8453  * ---------
8454  * Field 1 = 'P'
8455  * Field 2 = descriptive protocol name
8456  * Field 3 = protocol abbreviation
8457  *
8458  * Header Fields
8459  * -------------
8460  * Field 1 = 'F'
8461  * Field 2 = descriptive field name
8462  * Field 3 = field abbreviation
8463  * Field 4 = type ( textual representation of the the ftenum type )
8464  * Field 5 = parent protocol abbreviation
8465  * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
8466  * Field 7 = bitmask: format: hex: 0x....
8467  * Field 8 = blurb describing field
8468  */
8469 void
8470 proto_registrar_dump_fields(void)
8471 {
8472         header_field_info *hfinfo, *parent_hfinfo;
8473         int                i, len;
8474         const char        *enum_name;
8475         const char        *base_name;
8476         const char        *blurb;
8477         char               width[5];
8478
8479         len = gpa_hfinfo.len;
8480         for (i = 0; i < len ; i++) {
8481                 if (gpa_hfinfo.hfi[i] == NULL)
8482                         continue; /* This is a deregistered protocol or header field */
8483
8484                 PROTO_REGISTRAR_GET_NTH(i, hfinfo);
8485
8486                 /*
8487                  * Skip the pseudo-field for "proto_tree_add_text()" since
8488                  * we don't want it in the list of filterable fields.
8489                  */
8490                 if (hfinfo->id == hf_text_only)
8491                         continue;
8492
8493                 /* format for protocols */
8494                 if (proto_registrar_is_protocol(i)) {
8495                         printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
8496                 }
8497                 /* format for header fields */
8498                 else {
8499                         /*
8500                          * If this field isn't at the head of the list of
8501                          * fields with this name, skip this field - all
8502                          * fields with the same name are really just versions
8503                          * of the same field stored in different bits, and
8504                          * should have the same type/radix/value list, and
8505                          * just differ in their bit masks.      (If a field isn't
8506                          * a bitfield, but can be, say, 1 or 2 bytes long,
8507                          * it can just be made FT_UINT16, meaning the
8508                          * *maximum* length is 2 bytes, and be used
8509                          * for all lengths.)
8510                          */
8511                         if (hfinfo->same_name_prev_id != -1)
8512                                 continue;
8513
8514                         PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
8515
8516                         enum_name = ftype_name(hfinfo->type);
8517                         base_name = "";
8518
8519                         if (hfinfo->type == FT_UINT8  ||
8520                             hfinfo->type == FT_UINT16 ||
8521                             hfinfo->type == FT_UINT24 ||
8522                             hfinfo->type == FT_UINT32 ||
8523                             hfinfo->type == FT_UINT40 ||
8524                             hfinfo->type == FT_UINT48 ||
8525                             hfinfo->type == FT_UINT56 ||
8526                             hfinfo->type == FT_UINT64 ||
8527                             hfinfo->type == FT_INT8   ||
8528                             hfinfo->type == FT_INT16  ||
8529                             hfinfo->type == FT_INT24  ||
8530                             hfinfo->type == FT_INT32  ||
8531                             hfinfo->type == FT_INT40 ||
8532                             hfinfo->type == FT_INT48 ||
8533                             hfinfo->type == FT_INT56 ||
8534                             hfinfo->type == FT_INT64) {
8535
8536                                 switch (FIELD_DISPLAY(hfinfo->display)) {
8537                                         case BASE_NONE:
8538                                         case BASE_DEC:
8539                                         case BASE_HEX:
8540                                         case BASE_OCT:
8541                                         case BASE_DEC_HEX:
8542                                         case BASE_HEX_DEC:
8543                                         case BASE_CUSTOM:
8544                                         case BASE_PT_UDP:
8545                                         case BASE_PT_TCP:
8546                                         case BASE_PT_DCCP:
8547                                         case BASE_PT_SCTP:
8548                                                 base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display), hf_display, "????");
8549                                                 break;
8550                                         default:
8551                                                 base_name = "????";
8552                                                 break;
8553                                 }
8554                         } else if (hfinfo->type == FT_BOOLEAN) {
8555                                 /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
8556                                 g_snprintf(width, sizeof(width), "%d", hfinfo->display);
8557                                 base_name = width;
8558                         }
8559
8560                         blurb = hfinfo->blurb;
8561                         if (blurb == NULL)
8562                                 blurb = "";
8563                         else if (strlen(blurb) == 0)
8564                                 blurb = "\"\"";
8565
8566                         printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" G_GINT64_MODIFIER "x\t%s\n",
8567                                 hfinfo->name, hfinfo->abbrev, enum_name,
8568                                 parent_hfinfo->abbrev, base_name,
8569                                 hfinfo->bitmask, blurb);
8570                 }
8571         }
8572 }
8573
8574 /* Dumps field types and descriptive names to stdout. An independent
8575  * program can take this output and format it into nice tables or HTML or
8576  * whatever.
8577  *
8578  * There is one record per line. The fields are tab-delimited.
8579  *
8580  * Field 1 = field type name, e.g. FT_UINT8
8581  * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
8582  */
8583 void
8584 proto_registrar_dump_ftypes(void)
8585 {
8586         int fte;
8587
8588         for (fte = 0; fte < FT_NUM_TYPES; fte++) {
8589                 printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
8590         }
8591 }
8592
8593 /* This function indicates whether it's possible to construct a
8594  * "match selected" display filter string for the specified field,
8595  * returns an indication of whether it's possible, and, if it's
8596  * possible and "filter" is non-null, constructs the filter and
8597  * sets "*filter" to point to it.
8598  * You do not need to [g_]free() this string since it will be automatically
8599  * freed once the next packet is dissected.
8600  */
8601 static gboolean
8602 construct_match_selected_string(field_info *finfo, epan_dissect_t *edt,
8603                                 char **filter)
8604 {
8605         header_field_info *hfinfo;
8606         int                abbrev_len;
8607         char              *ptr;
8608         int                buf_len;
8609         int                dfilter_len, i;
8610         gint               start, length, length_remaining;
8611         guint8             c;
8612         gchar              is_signed_num = FALSE;
8613
8614         if (!finfo)
8615                 return FALSE;
8616
8617         hfinfo     = finfo->hfinfo;
8618         DISSECTOR_ASSERT(hfinfo);
8619         abbrev_len = (int) strlen(hfinfo->abbrev);
8620
8621         if (hfinfo->strings && (hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_NONE) {
8622                 const gchar *str = NULL;
8623
8624                 switch (hfinfo->type) {
8625
8626                 case FT_INT8:
8627                 case FT_INT16:
8628                 case FT_INT24:
8629                 case FT_INT32:
8630                         str = hf_try_val_to_str(fvalue_get_sinteger(&finfo->value), hfinfo);
8631                         break;
8632
8633                 case FT_UINT8:
8634                 case FT_UINT16:
8635                 case FT_UINT24:
8636                 case FT_UINT32:
8637                         str = hf_try_val_to_str(fvalue_get_uinteger(&finfo->value), hfinfo);
8638                         break;
8639
8640                 default:
8641                         break;
8642                 }
8643
8644                 if (str != NULL && filter != NULL) {
8645                         *filter = wmem_strdup_printf(NULL, "%s == \"%s\"", hfinfo->abbrev, str);
8646                         return TRUE;
8647                 }
8648         }
8649
8650         /*
8651          * XXX - we can't use the "val_to_string_repr" and "string_repr_len"
8652          * functions for FT_UINT and FT_INT types, as we choose the base in
8653          * the string expression based on the display base of the field.
8654          *
8655          * Note that the base does matter, as this is also used for
8656          * the protocolinfo tap.
8657          *
8658          * It might be nice to use them in "proto_item_fill_label()"
8659          * as well, although, there, you'd have to deal with the base
8660          * *and* with resolved values for addresses.
8661          *
8662          * Perhaps we need two different val_to_string routines, one
8663          * to generate items for display filters and one to generate
8664          * strings for display, and pass to both of them the
8665          * "display" and "strings" values in the header_field_info
8666          * structure for the field, so they can get the base and,
8667          * if the field is Boolean or an enumerated integer type,
8668          * the tables used to generate human-readable values.
8669          */
8670         switch (hfinfo->type) {
8671
8672                 case FT_INT8:
8673                 case FT_INT16:
8674                 case FT_INT24:
8675                 case FT_INT32:
8676                         is_signed_num = TRUE;
8677                         /* FALLTHRU */
8678                 case FT_UINT8:
8679                 case FT_UINT16:
8680                 case FT_UINT24:
8681                 case FT_UINT32:
8682                 case FT_FRAMENUM:
8683                         if (filter != NULL) {
8684                                 guint32 number;
8685
8686                                 char buf[32];
8687                                 const char *out;
8688
8689                                 if (is_signed_num)
8690                                         number = fvalue_get_sinteger(&finfo->value);
8691                                 else
8692                                         number = fvalue_get_uinteger(&finfo->value);
8693
8694                                 out = hfinfo_numeric_value_format(hfinfo, buf, number);
8695
8696                                 *filter = wmem_strdup_printf(NULL, "%s == %s", hfinfo->abbrev, out);
8697                         }
8698                         break;
8699
8700                 case FT_INT40:
8701                 case FT_INT48:
8702                 case FT_INT56:
8703                 case FT_INT64:
8704                         is_signed_num = TRUE;
8705                         /* FALLTHRU */
8706                 case FT_UINT40:
8707                 case FT_UINT48:
8708                 case FT_UINT56:
8709                 case FT_UINT64:
8710                         if (filter != NULL) {
8711                                 guint64 number;
8712
8713                                 char buf [48];
8714                                 const char *out;
8715
8716                                 if (is_signed_num)
8717                                         number = fvalue_get_sinteger64(&finfo->value);
8718                                 else
8719                                         number = fvalue_get_uinteger64(&finfo->value);
8720
8721                                 out = hfinfo_numeric_value_format64(hfinfo, buf, number);
8722
8723                                 *filter = wmem_strdup_printf(NULL, "%s == %s", hfinfo->abbrev, out);
8724                         }
8725                         break;
8726
8727                 case FT_PROTOCOL:
8728                         if (filter != NULL)
8729                                 *filter = wmem_strdup(NULL, finfo->hfinfo->abbrev);
8730                         break;
8731
8732                 case FT_NONE:
8733                         /*
8734                          * If the length is 0, just match the name of the
8735                          * field.
8736                          *
8737                          * (Also check for negative values, just in case,
8738                          * as we'll cast it to an unsigned value later.)
8739                          */
8740                         length = finfo->length;
8741                         if (length == 0) {
8742                                 if (filter != NULL)
8743                                         *filter = wmem_strdup(NULL, finfo->hfinfo->abbrev);
8744                                 break;
8745                         }
8746                         if (length < 0)
8747                                 return FALSE;
8748
8749                         /*
8750                          * This doesn't have a value, so we'd match
8751                          * on the raw bytes at this address.
8752                          *
8753                          * Should we be allowed to access to the raw bytes?
8754                          * If "edt" is NULL, the answer is "no".
8755                          */
8756                         if (edt == NULL)
8757                                 return FALSE;
8758
8759                         /*
8760                          * Is this field part of the raw frame tvbuff?
8761                          * If not, we can't use "frame[N:M]" to match
8762                          * it.
8763                          *
8764                          * XXX - should this be frame-relative, or
8765                          * protocol-relative?
8766                          *
8767                          * XXX - does this fallback for non-registered
8768                          * fields even make sense?
8769                          */
8770                         if (finfo->ds_tvb != edt->tvb)
8771                                 return FALSE;   /* you lose */
8772
8773                         /*
8774                          * Don't go past the end of that tvbuff.
8775                          */
8776                         length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
8777                         if (length > length_remaining)
8778                                 length = length_remaining;
8779                         if (length <= 0)
8780                                 return FALSE;
8781
8782                         if (filter != NULL) {
8783                                 start = finfo->start;
8784                                 buf_len = 32 + length * 3;
8785                                 *filter = (char *)wmem_alloc0(NULL, buf_len);
8786                                 ptr = *filter;
8787
8788                                 ptr += g_snprintf(ptr, (gulong) (buf_len-(ptr-*filter)),
8789                                         "frame[%d:%d] == ", finfo->start, length);
8790                                 for (i=0; i<length; i++) {
8791                                         c = tvb_get_guint8(finfo->ds_tvb, start);
8792                                         start++;
8793                                         if (i == 0 ) {
8794                                                 ptr += g_snprintf(ptr, (gulong) (buf_len-(ptr-*filter)), "%02x", c);
8795                                         }
8796                                         else {
8797                                                 ptr += g_snprintf(ptr, (gulong) (buf_len-(ptr-*filter)), ":%02x", c);
8798                                         }
8799                                 }
8800                         }
8801                         break;
8802
8803                 case FT_PCRE:
8804                         /* FT_PCRE never appears as a type for a registered field. It is
8805                          * only used internally. */
8806                         DISSECTOR_ASSERT_NOT_REACHED();
8807                         break;
8808
8809                 /* By default, use the fvalue's "to_string_repr" method. */
8810                 default:
8811                         /* Figure out the string length needed.
8812                          *      The ft_repr length.
8813                          *      4 bytes for " == ".
8814                          *      1 byte for trailing NUL.
8815                          */
8816                         if (filter != NULL) {
8817                                 char* str;
8818                                 dfilter_len = fvalue_string_repr_len(&finfo->value,
8819                                                 FTREPR_DFILTER, finfo->hfinfo->display);
8820                                 dfilter_len += abbrev_len + 4 + 1;
8821                                 *filter = (char *)wmem_alloc0(NULL, dfilter_len);
8822
8823                                 /* Create the string */
8824                                 str = fvalue_to_string_repr(NULL, &finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
8825                                 g_snprintf(*filter, dfilter_len, "%s == %s", hfinfo->abbrev, str);
8826                                 wmem_free(NULL, str);
8827                         }
8828                         break;
8829         }
8830
8831         return TRUE;
8832 }
8833
8834 /*
8835  * Returns TRUE if we can do a "match selected" on the field, FALSE
8836  * otherwise.
8837  */
8838 gboolean
8839 proto_can_match_selected(field_info *finfo, epan_dissect_t *edt)
8840 {
8841         return construct_match_selected_string(finfo, edt, NULL);
8842 }
8843
8844 /* This function attempts to construct a "match selected" display filter
8845  * string for the specified field; if it can do so, it returns a pointer
8846  * to the string, otherwise it returns NULL.
8847  *
8848  * The string is allocated with packet lifetime scope.
8849  * You do not need to [g_]free() this string since it will be automatically
8850  * freed once the next packet is dissected.
8851  */
8852 char *
8853 proto_construct_match_selected_string(field_info *finfo, epan_dissect_t *edt)
8854 {
8855         char *filter = NULL;
8856
8857         if (!construct_match_selected_string(finfo, edt, &filter))
8858         {
8859                 wmem_free(NULL, filter);
8860                 return NULL;
8861         }
8862         return filter;
8863 }
8864
8865 /* This function is common code for all proto_tree_add_bitmask... functions.
8866  */
8867
8868 static gboolean
8869 proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
8870                             const int len, const gint ett, const int **fields,
8871                             const int flags, gboolean first,
8872                             gboolean use_parent_tree,
8873                             proto_tree* tree, guint64 value)
8874 {
8875         guint              bitshift;
8876         guint64            available_bits = 0;
8877         guint64            tmpval;
8878         header_field_info *hf;
8879
8880         if (len < 0 || len > 8)
8881                 g_assert_not_reached();
8882         bitshift = (8 - (guint)len)*8;
8883         available_bits = G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF) >> bitshift;
8884
8885         if (use_parent_tree == FALSE)
8886                 tree = proto_item_add_subtree(item, ett);
8887
8888         while (*fields) {
8889                 guint64 present_bits;
8890                 PROTO_REGISTRAR_GET_NTH(**fields,hf);
8891                 DISSECTOR_ASSERT_HINT(hf->bitmask != 0, hf->abbrev);
8892
8893                 /* Skip fields that aren't fully present */
8894                 present_bits = available_bits & hf->bitmask;
8895                 if (present_bits != hf->bitmask) {
8896                         fields++;
8897                         continue;
8898                 }
8899
8900                 switch (hf->type) {
8901                 case FT_INT8:
8902                 case FT_UINT8:
8903                 case FT_INT16:
8904                 case FT_UINT16:
8905                 case FT_INT24:
8906                 case FT_UINT24:
8907                 case FT_INT32:
8908                 case FT_UINT32:
8909                         proto_tree_add_uint(tree, **fields, tvb, offset, len, (guint32)value);
8910                         break;
8911
8912                 case FT_INT40:
8913                 case FT_UINT40:
8914                 case FT_INT48:
8915                 case FT_UINT48:
8916                 case FT_INT56:
8917                 case FT_UINT56:
8918                 case FT_INT64:
8919                 case FT_UINT64:
8920                         proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
8921                         break;
8922
8923                 case FT_BOOLEAN:
8924                         proto_tree_add_boolean64(tree, **fields, tvb, offset, len, value);
8925                         break;
8926
8927                 default:
8928                         DISSECTOR_ASSERT_NOT_REACHED();
8929                         break;
8930                 }
8931                 if (flags & BMT_NO_APPEND) {
8932                         fields++;
8933                         continue;
8934                 }
8935                 tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
8936
8937                 switch (hf->type) {
8938                 case FT_INT8:
8939                 case FT_UINT8:
8940                 case FT_INT16:
8941                 case FT_UINT16:
8942                 case FT_INT24:
8943                 case FT_UINT24:
8944                 case FT_INT32:
8945                 case FT_UINT32:
8946                 case FT_INT40:
8947                 case FT_UINT40:
8948                 case FT_INT48:
8949                 case FT_UINT48:
8950                 case FT_INT56:
8951                 case FT_UINT56:
8952                 case FT_INT64:
8953                 case FT_UINT64:
8954                         if (hf->display == BASE_CUSTOM) {
8955                                 gchar lbl[ITEM_LABEL_LENGTH];
8956                                 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
8957
8958                                 DISSECTOR_ASSERT(fmtfunc);
8959                                 fmtfunc(lbl, (guint32) tmpval);
8960                                 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
8961                                                 hf->name, lbl);
8962                                 first = FALSE;
8963                         }
8964                         else if (hf->strings) {
8965                                 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
8966                                                        hf->name, hf_try_val_to_str_const((guint32) tmpval, hf, "Unknown"));
8967                                 first = FALSE;
8968                         }
8969                         else if (!(flags & BMT_NO_INT)) {
8970                                 char buf[32];
8971                                 const char *out;
8972
8973                                 if (!first) {
8974                                         proto_item_append_text(item, ", ");
8975                                 }
8976
8977                                 out = hfinfo_number_value_format(hf, buf, (guint32) tmpval);
8978                                 proto_item_append_text(item, "%s: %s", hf->name, out);
8979                                 first = FALSE;
8980                         }
8981
8982                         break;
8983                 case FT_BOOLEAN:
8984                         if (hf->strings && !(flags & BMT_NO_TFS)) {
8985                                 /* If we have true/false strings, emit full - otherwise messages
8986                                    might look weird */
8987                                 const struct true_false_string *tfs =
8988                                         (const struct true_false_string *)hf->strings;
8989
8990                                 if (tmpval) {
8991                                         proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
8992                                                         hf->name, tfs->true_string);
8993                                         first = FALSE;
8994                                 } else if (!(flags & BMT_NO_FALSE)) {
8995                                         proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
8996                                                         hf->name, tfs->false_string);
8997                                         first = FALSE;
8998                                 }
8999                         } else if (hf->bitmask & value) {
9000                                 /* If the flag is set, show the name */
9001                                 proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
9002                                 first = FALSE;
9003                         }
9004                         break;
9005                 default:
9006                         DISSECTOR_ASSERT_NOT_REACHED();
9007                         break;
9008                 }
9009
9010                 fields++;
9011         }
9012
9013         return first;
9014 }
9015
9016 /* This function will dissect a sequence of bytes that describe a
9017  * bitmask and supply the value of that sequence through a pointer.
9018  * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
9019  * to be dissected.
9020  * This field will form an expansion under which the individual fields of the
9021  * bitmask is dissected and displayed.
9022  * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
9023  *
9024  * fields is an array of pointers to int that lists all the fields of the
9025  * bitmask. These fields can be either of the type FT_BOOLEAN for flags
9026  * or another integer of the same type/size as hf_hdr with a mask specified.
9027  * This array is terminated by a NULL entry.
9028  *
9029  * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
9030  * FT_integer fields that have a value_string attached will have the
9031  * matched string displayed on the expansion line.
9032  */
9033 proto_item *
9034 proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
9035                        const guint offset, const int hf_hdr,
9036                        const gint ett, const int **fields,
9037                        const guint encoding, guint64 *retval)
9038 {
9039         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);
9040 }
9041
9042 /* This function will dissect a sequence of bytes that describe a
9043  * bitmask.
9044  * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
9045  * to be dissected.
9046  * This field will form an expansion under which the individual fields of the
9047  * bitmask is dissected and displayed.
9048  * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
9049  *
9050  * fields is an array of pointers to int that lists all the fields of the
9051  * bitmask. These fields can be either of the type FT_BOOLEAN for flags
9052  * or another integer of the same type/size as hf_hdr with a mask specified.
9053  * This array is terminated by a NULL entry.
9054  *
9055  * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
9056  * FT_integer fields that have a value_string attached will have the
9057  * matched string displayed on the expansion line.
9058  */
9059 proto_item *
9060 proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
9061                        const guint offset, const int hf_hdr,
9062                        const gint ett, const int **fields,
9063                        const guint encoding)
9064 {
9065         return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT|BMT_NO_TFS);
9066 }
9067
9068 /* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
9069  * what data is appended to the header.
9070  */
9071 proto_item *
9072 proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
9073                 const int hf_hdr, const gint ett, const int **fields, const guint encoding, const int flags,
9074                 guint64 *retval)
9075 {
9076         proto_item        *item = NULL;
9077         header_field_info *hf;
9078         int                len;
9079         guint64            value;
9080
9081         PROTO_REGISTRAR_GET_NTH(hf_hdr,hf);
9082         DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
9083         len = ftype_length(hf->type);
9084         value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
9085
9086         if (parent_tree) {
9087                 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
9088                 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
9089                     flags, FALSE, FALSE, NULL, value);
9090         }
9091
9092         *retval = value;
9093         return item;
9094 }
9095
9096 /* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
9097  * what data is appended to the header.
9098  */
9099 proto_item *
9100 proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
9101                 const int hf_hdr, const gint ett, const int **fields, const guint encoding, const int flags)
9102 {
9103         proto_item        *item = NULL;
9104         header_field_info *hf;
9105         int                len;
9106         guint64            value;
9107
9108         PROTO_REGISTRAR_GET_NTH(hf_hdr,hf);
9109         DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
9110
9111         if (parent_tree) {
9112                 len = ftype_length(hf->type);
9113                 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
9114                 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
9115                 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
9116                     flags, FALSE, FALSE, NULL, value);
9117         }
9118
9119         return item;
9120 }
9121
9122 /* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
9123    can't be retrieved directly from tvb) */
9124 proto_item *
9125 proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
9126                 const int hf_hdr, const gint ett, const int **fields, const guint64 value)
9127 {
9128         return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
9129                                                 hf_hdr, ett, fields, value, BMT_NO_INT|BMT_NO_TFS);
9130 }
9131
9132 /* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
9133 WS_DLL_PUBLIC proto_item *
9134 proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const guint offset,
9135                 const int hf_hdr, const gint ett, const int **fields, const guint64 value, const int flags)
9136 {
9137         proto_item        *item = NULL;
9138         header_field_info *hf;
9139         int                len;
9140
9141         PROTO_REGISTRAR_GET_NTH(hf_hdr,hf);
9142         DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
9143         len = ftype_length(hf->type);
9144
9145         if (parent_tree) {
9146                 if (len <= 4)
9147                         item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (guint32)value);
9148                 else
9149                         item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
9150
9151                 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
9152                     flags, FALSE, FALSE, NULL, value);
9153         }
9154
9155         return item;
9156 }
9157
9158 /* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
9159 void
9160 proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const guint offset,
9161                                                                 const int len, const int **fields, const guint encoding)
9162 {
9163         guint64 value;
9164
9165         if (tree) {
9166                 value = get_uint64_value(tree, tvb, offset, len, encoding);
9167                 proto_item_add_bitmask_tree(NULL, tvb, offset, len, -1, fields,
9168                     BMT_NO_APPEND, FALSE, TRUE, tree, value);
9169         }
9170 }
9171
9172 WS_DLL_PUBLIC void
9173 proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const guint offset,
9174                                                                 const int len, const int **fields, const guint64 value)
9175 {
9176         if (tree) {
9177                 proto_item_add_bitmask_tree(NULL, tvb, offset, len, -1, fields,
9178                     BMT_NO_APPEND, FALSE, TRUE, tree, value);
9179         }
9180 }
9181
9182
9183 /* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
9184  * This is intended to support bitmask fields whose lengths can vary, perhaps
9185  * as the underlying standard evolves over time.
9186  * With this API there is the possibility of being called to display more or
9187  * less data than the dissector was coded to support.
9188  * In such cases, it is assumed that bitmasks are extended on the MSb end.
9189  * Thus when presented with "too much" or "too little" data, MSbits will be
9190  * ignored or MSfields sacrificed.
9191  *
9192  * Only fields for which all defined bits are available are displayed.
9193  */
9194 proto_item *
9195 proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
9196                        const guint offset,  const guint len, const int hf_hdr,
9197                        const gint ett, const int **fields, struct expert_field* exp,
9198                        const guint encoding)
9199 {
9200         proto_item        *item = NULL;
9201         header_field_info *hf;
9202         guint   decodable_len;
9203         guint   decodable_offset;
9204         guint32 decodable_value;
9205         guint64 value;
9206
9207         PROTO_REGISTRAR_GET_NTH(hf_hdr, hf);
9208         DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
9209
9210         decodable_offset = offset;
9211         decodable_len = MIN(len, (guint) ftype_length(hf->type));
9212
9213         /* If we are ftype_length-limited,
9214          * make sure we decode as many LSBs as possible.
9215          */
9216         if (encoding == ENC_BIG_ENDIAN) {
9217                 decodable_offset += (len - decodable_len);
9218         }
9219
9220         if (parent_tree) {
9221                 decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
9222                                                  decodable_len, encoding);
9223
9224                 /* The root item covers all the bytes even if we can't decode them all */
9225                 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
9226                                            decodable_value);
9227         }
9228
9229         if (decodable_len < len) {
9230                 /* Dissector likely requires updating for new protocol revision */
9231                 expert_add_info_format(NULL, item, exp,
9232                                        "Only least-significant %d of %d bytes decoded",
9233                                        decodable_len, len);
9234         }
9235
9236         if (item) {
9237                 value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
9238                 proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
9239                     ett, fields, BMT_NO_INT|BMT_NO_TFS, FALSE, FALSE, NULL, value);
9240         }
9241
9242         return item;
9243 }
9244
9245 /* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
9246 proto_item *
9247 proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
9248                             const guint offset, const guint len,
9249                             const char *name, const char *fallback,
9250                             const gint ett, const int **fields,
9251                             const guint encoding, const int flags)
9252 {
9253         proto_item *item = NULL;
9254         guint64     value;
9255
9256         if (parent_tree) {
9257                 item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
9258                 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
9259                 if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
9260                     flags, TRUE, FALSE, NULL, value) && fallback) {
9261                         /* Still at first item - append 'fallback' text if any */
9262                         proto_item_append_text(item, "%s", fallback);
9263                 }
9264         }
9265
9266         return item;
9267 }
9268
9269 proto_item *
9270 proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
9271                          const guint bit_offset, const gint no_of_bits,
9272                          const guint encoding)
9273 {
9274         header_field_info *hfinfo;
9275         gint               octet_length;
9276         gint               octet_offset;
9277
9278         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
9279
9280         octet_length = (no_of_bits + 7) >> 3;
9281         octet_offset = bit_offset >> 3;
9282         test_length(hfinfo, tvb, octet_offset, octet_length);
9283
9284         /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
9285          * but only after doing a bunch more work (which we can, in the common
9286          * case, shortcut here).
9287          */
9288         CHECK_FOR_NULL_TREE(tree);
9289         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
9290
9291         return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL, encoding);
9292 }
9293
9294 /*
9295  * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
9296  * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
9297  * Offset should be given in bits from the start of the tvb.
9298  */
9299
9300 static proto_item *
9301 _proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
9302                             const guint bit_offset, const gint no_of_bits,
9303                             guint64 *return_value, const guint encoding)
9304 {
9305         gint     offset;
9306         guint    length;
9307         guint8   tot_no_bits;
9308         char    *bf_str;
9309         char     lbl_str[ITEM_LABEL_LENGTH];
9310         guint64  value = 0;
9311
9312         proto_item        *pi;
9313         header_field_info *hf_field;
9314
9315         const true_false_string *tfstring;
9316
9317         /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
9318         PROTO_REGISTRAR_GET_NTH(hfindex, hf_field);
9319
9320         if (hf_field->bitmask != 0) {
9321                 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
9322                                         "Incompatible use of proto_tree_add_bits_ret_val"
9323                                         " with field '%s' (%s) with bitmask != 0",
9324                                         hf_field->abbrev, hf_field->name));
9325         }
9326
9327         DISSECTOR_ASSERT(no_of_bits >  0);
9328
9329         /* Byte align offset */
9330         offset = bit_offset>>3;
9331
9332         /*
9333          * Calculate the number of octets used to hold the bits
9334          */
9335         tot_no_bits = ((bit_offset&0x7) + no_of_bits);
9336         length = (tot_no_bits + 7) >> 3;
9337
9338         if (no_of_bits < 65) {
9339                 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
9340         } else {
9341                 DISSECTOR_ASSERT_NOT_REACHED();
9342                 return NULL;
9343         }
9344
9345         /* Sign extend for signed types */
9346         switch (hf_field->type) {
9347                 case FT_INT8:
9348                 case FT_INT16:
9349                 case FT_INT24:
9350                 case FT_INT32:
9351                 case FT_INT40:
9352                 case FT_INT48:
9353                 case FT_INT56:
9354                 case FT_INT64:
9355                         value = ws_sign_ext64(value, no_of_bits);
9356                         break;
9357
9358                 default:
9359                         break;
9360         }
9361
9362         if (return_value) {
9363                 *return_value = value;
9364         }
9365
9366         /* Coast clear. Try and fake it */
9367         CHECK_FOR_NULL_TREE(tree);
9368         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
9369
9370         bf_str = decode_bits_in_field(bit_offset, no_of_bits, value);
9371
9372         switch (hf_field->type) {
9373         case FT_BOOLEAN:
9374                 /* Boolean field */
9375                 tfstring = (const true_false_string *) &tfs_true_false;
9376                 if (hf_field->strings)
9377                         tfstring = (const true_false_string *)hf_field->strings;
9378                 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, (guint32)value,
9379                         "%s = %s: %s",
9380                         bf_str, hf_field->name,
9381                         (guint64)value ? tfstring->true_string : tfstring->false_string);
9382                 break;
9383
9384         case FT_UINT8:
9385         case FT_UINT16:
9386         case FT_UINT24:
9387         case FT_UINT32:
9388                 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (guint32)value);
9389                 fill_label_number(PITEM_FINFO(pi), lbl_str, FALSE);
9390                 break;
9391
9392         case FT_INT8:
9393         case FT_INT16:
9394         case FT_INT24:
9395         case FT_INT32:
9396                 pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (gint32)value);
9397                 fill_label_number(PITEM_FINFO(pi), lbl_str, TRUE);
9398                 break;
9399
9400         case FT_UINT40:
9401         case FT_UINT48:
9402         case FT_UINT56:
9403         case FT_UINT64:
9404                 pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
9405                 fill_label_number64(PITEM_FINFO(pi), lbl_str, FALSE);
9406                 break;
9407
9408         case FT_INT40:
9409         case FT_INT48:
9410         case FT_INT56:
9411         case FT_INT64:
9412                 pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (gint64)value);
9413                 fill_label_number64(PITEM_FINFO(pi), lbl_str, TRUE);
9414                 break;
9415
9416         default:
9417                 DISSECTOR_ASSERT_NOT_REACHED();
9418                 return NULL;
9419                 break;
9420         }
9421
9422         proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
9423         return pi;
9424 }
9425
9426 proto_item *
9427 proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
9428                                        const guint bit_offset, const crumb_spec_t *crumb_spec,
9429                                        guint64 *return_value)
9430 {
9431         proto_item *pi;
9432         gint        no_of_bits;
9433         gint        octet_offset;
9434         guint       mask_initial_bit_offset;
9435         guint       mask_greatest_bit_offset;
9436         guint       octet_length;
9437         guint8      i;
9438         char        bf_str[256];
9439         char        lbl_str[ITEM_LABEL_LENGTH];
9440         guint64     value;
9441         guint64     composite_bitmask;
9442         guint64     composite_bitmap;
9443
9444         header_field_info       *hf_field;
9445         const true_false_string *tfstring;
9446
9447         /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
9448         PROTO_REGISTRAR_GET_NTH(hfindex, hf_field);
9449
9450         if (hf_field->bitmask != 0) {
9451                 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
9452                                         "Incompatible use of proto_tree_add_split_bits_item_ret_val"
9453                                         " with field '%s' (%s) with bitmask != 0",
9454                                         hf_field->abbrev, hf_field->name));
9455         }
9456
9457         mask_initial_bit_offset = bit_offset % 8;
9458
9459         no_of_bits = 0;
9460         value      = 0;
9461         i          = 0;
9462         mask_greatest_bit_offset = 0;
9463         composite_bitmask        = 0;
9464         composite_bitmap         = 0;
9465
9466         while (crumb_spec[i].crumb_bit_length != 0) {
9467                 guint64 crumb_mask, crumb_value;
9468                 guint8  crumb_end_bit_offset;
9469
9470                 DISSECTOR_ASSERT(i < 64);
9471                 crumb_value = tvb_get_bits64(tvb,
9472                                              bit_offset + crumb_spec[i].crumb_bit_offset,
9473                                              crumb_spec[i].crumb_bit_length,
9474                                              ENC_BIG_ENDIAN);
9475                 value      += crumb_value;
9476                 no_of_bits += crumb_spec[i].crumb_bit_length;
9477
9478                 /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
9479                    octet containing the initial offset.
9480                    If the mask is beyond 32 bits, then give up on bit map display.
9481                    This could be improved in future, probably showing a table
9482                    of 32 or 64 bits per row */
9483                 if (mask_greatest_bit_offset < 32) {
9484                         crumb_end_bit_offset = mask_initial_bit_offset
9485                                 + crumb_spec[i].crumb_bit_offset
9486                                 + crumb_spec[i].crumb_bit_length;
9487                         crumb_mask = (G_GUINT64_CONSTANT(1) << crumb_spec[i].crumb_bit_length) - 1;
9488
9489                         if (crumb_end_bit_offset > mask_greatest_bit_offset) {
9490                                 mask_greatest_bit_offset = crumb_end_bit_offset;
9491                         }
9492                         composite_bitmask |= (crumb_mask  << (64 - crumb_end_bit_offset));
9493                         composite_bitmap  |= (crumb_value << (64 - crumb_end_bit_offset));
9494                 }
9495                 /* Shift left for the next segment */
9496                 value <<= crumb_spec[++i].crumb_bit_length;
9497         }
9498
9499         /* Sign extend for signed types */
9500         switch (hf_field->type) {
9501                 case FT_INT8:
9502                 case FT_INT16:
9503                 case FT_INT24:
9504                 case FT_INT32:
9505                 case FT_INT40:
9506                 case FT_INT48:
9507                 case FT_INT56:
9508                 case FT_INT64:
9509                         value = ws_sign_ext64(value, no_of_bits);
9510                         break;
9511                 default:
9512                         break;
9513         }
9514
9515         if (return_value) {
9516                 *return_value = value;
9517         }
9518
9519         /* Coast clear. Try and fake it */
9520         CHECK_FOR_NULL_TREE(tree);
9521         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
9522
9523         /* initialise the format string */
9524         bf_str[0] = '\0';
9525
9526         octet_offset = bit_offset >> 3;
9527
9528         /* Round up mask length to nearest octet */
9529         octet_length = ((mask_greatest_bit_offset + 7) >> 3);
9530         mask_greatest_bit_offset = octet_length << 3;
9531
9532         /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
9533            It would be a useful enhancement to eliminate this restriction. */
9534         if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
9535                 other_decode_bitfield_value(bf_str,
9536                                             (guint32)(composite_bitmap  >> (64 - mask_greatest_bit_offset)),
9537                                             (guint32)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
9538                                             mask_greatest_bit_offset);
9539         }
9540
9541         switch (hf_field->type) {
9542         case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
9543                 /* Boolean field */
9544                 tfstring = (const true_false_string *) &tfs_true_false;
9545                 if (hf_field->strings)
9546                         tfstring = (const true_false_string *) hf_field->strings;
9547                 return proto_tree_add_boolean_format(tree, hfindex,
9548                                                      tvb, octet_offset, octet_length, (guint32)value,
9549                                                      "%s = %s: %s",
9550                                                      bf_str, hf_field->name,
9551                                                      (guint64)value ? tfstring->true_string : tfstring->false_string);
9552                 break;
9553
9554         case FT_UINT8:
9555         case FT_UINT16:
9556         case FT_UINT24:
9557         case FT_UINT32:
9558                 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (guint32)value);
9559                 fill_label_number(PITEM_FINFO(pi), lbl_str, FALSE);
9560                 break;
9561
9562         case FT_INT8:
9563         case FT_INT16:
9564         case FT_INT24:
9565         case FT_INT32:
9566                 pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (gint32)value);
9567                 fill_label_number(PITEM_FINFO(pi), lbl_str, TRUE);
9568                 break;
9569
9570         case FT_UINT40:
9571         case FT_UINT48:
9572         case FT_UINT56:
9573         case FT_UINT64:
9574                 pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
9575                 fill_label_number64(PITEM_FINFO(pi), lbl_str, FALSE);
9576                 break;
9577
9578         case FT_INT40:
9579         case FT_INT48:
9580         case FT_INT56:
9581         case FT_INT64:
9582                 pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (gint64)value);
9583                 fill_label_number64(PITEM_FINFO(pi), lbl_str, TRUE);
9584                 break;
9585
9586         default:
9587                 DISSECTOR_ASSERT_NOT_REACHED();
9588                 return NULL;
9589                 break;
9590         }
9591         proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
9592         return pi;
9593 }
9594
9595 void
9596 proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const guint bit_offset,
9597                                 const crumb_spec_t *crumb_spec, guint16 crumb_index)
9598 {
9599         header_field_info *hfinfo;
9600
9601         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
9602         proto_tree_add_text_internal(tree, tvb,
9603                             bit_offset >> 3,
9604                             ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1,
9605                             "%s crumb %d of %s (decoded above)",
9606                             decode_bits_in_field(bit_offset, crumb_spec[crumb_index].crumb_bit_length,
9607                                                  tvb_get_bits(tvb,
9608                                                               bit_offset,
9609                                                               crumb_spec[crumb_index].crumb_bit_length,
9610                                                               ENC_BIG_ENDIAN)),
9611                             crumb_index,
9612                             hfinfo->name);
9613 }
9614
9615 proto_item *
9616 proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
9617                             const guint bit_offset, const gint no_of_bits,
9618                             guint64 *return_value, const guint encoding)
9619 {
9620         proto_item *item;
9621
9622         if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
9623                                                  bit_offset, no_of_bits,
9624                                                  return_value, encoding))) {
9625                 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset));
9626                 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_SIZE(no_of_bits));
9627         }
9628         return item;
9629 }
9630
9631 static proto_item *
9632 _proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
9633                                  tvbuff_t *tvb, const guint bit_offset,
9634                                  const gint no_of_bits, void *value_ptr,
9635                                  gchar *value_str)
9636 {
9637         gint     offset;
9638         guint    length;
9639         guint8   tot_no_bits;
9640         char    *str;
9641         guint64  value = 0;
9642         header_field_info *hf_field;
9643
9644         /* We do not have to return a value, try to fake it as soon as possible */
9645         CHECK_FOR_NULL_TREE(tree);
9646         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
9647
9648         if (hf_field->bitmask != 0) {
9649                 REPORT_DISSECTOR_BUG(wmem_strdup_printf(wmem_packet_scope(),
9650                                         "Incompatible use of proto_tree_add_bits_format_value"
9651                                         " with field '%s' (%s) with bitmask != 0",
9652                                         hf_field->abbrev, hf_field->name));
9653         }
9654
9655         DISSECTOR_ASSERT(no_of_bits > 0);
9656
9657         /* Byte align offset */
9658         offset = bit_offset>>3;
9659
9660         /*
9661          * Calculate the number of octets used to hold the bits
9662          */
9663         tot_no_bits = ((bit_offset&0x7) + no_of_bits);
9664         length      = tot_no_bits>>3;
9665         /* If we are using part of the next octet, increase length by 1 */
9666         if (tot_no_bits & 0x07)
9667                 length++;
9668
9669         if (no_of_bits < 65) {
9670                 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, ENC_BIG_ENDIAN);
9671         } else {
9672                 DISSECTOR_ASSERT_NOT_REACHED();
9673                 return NULL;
9674         }
9675
9676         str = decode_bits_in_field(bit_offset, no_of_bits, value);
9677
9678         g_strlcat(str, " = ", 256+64);
9679         g_strlcat(str, hf_field->name, 256+64);
9680
9681         /*
9682          * This function does not receive an actual value but a dimensionless pointer to that value.
9683          * For this reason, the type of the header field is examined in order to determine
9684          * what kind of value we should read from this address.
9685          * The caller of this function must make sure that for the specific header field type the address of
9686          * a compatible value is provided.
9687          */
9688         switch (hf_field->type) {
9689         case FT_BOOLEAN:
9690                 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(guint32 *)value_ptr,
9691                                                      "%s: %s", str, value_str);
9692                 break;
9693
9694         case FT_UINT8:
9695         case FT_UINT16:
9696         case FT_UINT24:
9697         case FT_UINT32:
9698                 return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(guint32 *)value_ptr,
9699                                                   "%s: %s", str, value_str);
9700                 break;
9701
9702         case FT_UINT40:
9703         case FT_UINT48:
9704         case FT_UINT56:
9705         case FT_UINT64:
9706                 return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(guint64 *)value_ptr,
9707                                                     "%s: %s", str, value_str);
9708                 break;
9709
9710         case FT_INT8:
9711         case FT_INT16:
9712         case FT_INT24:
9713         case FT_INT32:
9714                 return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(gint32 *)value_ptr,
9715                                                  "%s: %s", str, value_str);
9716                 break;
9717
9718         case FT_INT40:
9719         case FT_INT48:
9720         case FT_INT56:
9721         case FT_INT64:
9722                 return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(gint64 *)value_ptr,
9723                                                    "%s: %s", str, value_str);
9724                 break;
9725
9726         case FT_FLOAT:
9727                 return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
9728                                                    "%s: %s", str, value_str);
9729                 break;
9730
9731         default:
9732                 DISSECTOR_ASSERT_NOT_REACHED();
9733                 return NULL;
9734                 break;
9735         }
9736 }
9737
9738 static proto_item *
9739 proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
9740                                  tvbuff_t *tvb, const guint bit_offset,
9741                                  const gint no_of_bits, void *value_ptr,
9742                                  gchar *value_str)
9743 {
9744         proto_item *item;
9745
9746         if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
9747                                                       tvb, bit_offset, no_of_bits,
9748                                                       value_ptr, value_str))) {
9749                 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset));
9750                 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_SIZE(no_of_bits));
9751         }
9752         return item;
9753 }
9754
9755 #define CREATE_VALUE_STRING(dst,format,ap) \
9756         va_start(ap, format); \
9757         dst = wmem_strdup_vprintf(wmem_packet_scope(), format, ap); \
9758         va_end(ap);
9759
9760 proto_item *
9761 proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
9762                                       tvbuff_t *tvb, const guint bit_offset,
9763                                       const gint no_of_bits, guint32 value,
9764                                       const char *format, ...)
9765 {
9766         va_list ap;
9767         gchar  *dst;
9768         header_field_info *hf_field;
9769
9770         CHECK_FOR_NULL_TREE(tree);
9771
9772         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
9773
9774         switch (hf_field->type) {
9775                 case FT_UINT8:
9776                 case FT_UINT16:
9777                 case FT_UINT24:
9778                 case FT_UINT32:
9779                         break;
9780
9781                 default:
9782                         DISSECTOR_ASSERT_NOT_REACHED();
9783                         return NULL;
9784                         break;
9785         }
9786
9787         CREATE_VALUE_STRING(dst, format, ap);
9788
9789         return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
9790 }
9791
9792 proto_item *
9793 proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
9794                                       tvbuff_t *tvb, const guint bit_offset,
9795                                       const gint no_of_bits, guint64 value,
9796                                       const char *format, ...)
9797 {
9798         va_list ap;
9799         gchar  *dst;
9800         header_field_info *hf_field;
9801
9802         CHECK_FOR_NULL_TREE(tree);
9803
9804         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
9805
9806         switch (hf_field->type) {
9807                 case FT_UINT40:
9808                 case FT_UINT48:
9809                 case FT_UINT56:
9810                 case FT_UINT64:
9811                         break;
9812
9813                 default:
9814                         DISSECTOR_ASSERT_NOT_REACHED();
9815                         return NULL;
9816                         break;
9817         }
9818
9819         CREATE_VALUE_STRING(dst, format, ap);
9820
9821         return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
9822 }
9823
9824 proto_item *
9825 proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
9826                                        tvbuff_t *tvb, const guint bit_offset,
9827                                        const gint no_of_bits, float value,
9828                                        const char *format, ...)
9829 {
9830         va_list ap;
9831         gchar  *dst;
9832         header_field_info *hf_field;
9833
9834         CHECK_FOR_NULL_TREE(tree);
9835
9836         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
9837
9838         DISSECTOR_ASSERT_FIELD_TYPE(hf_field, FT_FLOAT);
9839
9840         CREATE_VALUE_STRING(dst, format, ap);
9841
9842         return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
9843 }
9844
9845 proto_item *
9846 proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
9847                                      tvbuff_t *tvb, const guint bit_offset,
9848                                      const gint no_of_bits, gint32 value,
9849                                      const char *format, ...)
9850 {
9851         va_list ap;
9852         gchar  *dst;
9853         header_field_info *hf_field;
9854
9855         CHECK_FOR_NULL_TREE(tree);
9856
9857         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
9858
9859         switch (hf_field->type) {
9860                 case FT_INT8:
9861                 case FT_INT16:
9862                 case FT_INT24:
9863                 case FT_INT32:
9864                         break;
9865
9866                 default:
9867                         DISSECTOR_ASSERT_NOT_REACHED();
9868                         return NULL;
9869                         break;
9870         }
9871
9872         CREATE_VALUE_STRING(dst, format, ap);
9873
9874         return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
9875 }
9876
9877 proto_item *
9878 proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
9879                                      tvbuff_t *tvb, const guint bit_offset,
9880                                      const gint no_of_bits, gint64 value,
9881                                      const char *format, ...)
9882 {
9883         va_list ap;
9884         gchar  *dst;
9885         header_field_info *hf_field;
9886
9887         CHECK_FOR_NULL_TREE(tree);
9888
9889         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
9890
9891         switch (hf_field->type) {
9892                 case FT_INT40:
9893                 case FT_INT48:
9894                 case FT_INT56:
9895                 case FT_INT64:
9896                         break;
9897
9898                 default:
9899                         DISSECTOR_ASSERT_NOT_REACHED();
9900                         return NULL;
9901                         break;
9902         }
9903
9904         CREATE_VALUE_STRING(dst, format, ap);
9905
9906         return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
9907 }
9908
9909 proto_item *
9910 proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
9911                                          tvbuff_t *tvb, const guint bit_offset,
9912                                          const gint no_of_bits, guint32 value,
9913                                          const char *format, ...)
9914 {
9915         va_list ap;
9916         gchar  *dst;
9917         header_field_info *hf_field;
9918
9919         CHECK_FOR_NULL_TREE(tree);
9920
9921         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
9922
9923         DISSECTOR_ASSERT_FIELD_TYPE(hf_field, FT_BOOLEAN);
9924
9925         CREATE_VALUE_STRING(dst, format, ap);
9926
9927         return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
9928 }
9929
9930 proto_item *
9931 proto_tree_add_boolean_bits_format_value64(proto_tree *tree, const int hfindex,
9932                                          tvbuff_t *tvb, const guint bit_offset,
9933                                          const gint no_of_bits, guint64 value,
9934                                          const char *format, ...)
9935 {
9936         va_list ap;
9937         gchar  *dst;
9938         header_field_info *hf_field;
9939
9940         CHECK_FOR_NULL_TREE(tree);
9941
9942         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
9943
9944         DISSECTOR_ASSERT(hf_field->type == FT_BOOLEAN);
9945
9946         CREATE_VALUE_STRING(dst, format, ap);
9947
9948         return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
9949 }
9950
9951 proto_item *
9952 proto_tree_add_ts_23_038_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
9953         const guint bit_offset, const gint no_of_chars)
9954 {
9955         proto_item        *pi;
9956         header_field_info *hfinfo;
9957         gint               byte_length;
9958         gint               byte_offset;
9959         gchar             *string;
9960
9961         CHECK_FOR_NULL_TREE(tree);
9962
9963         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
9964
9965         DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_STRING);
9966
9967         byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
9968         byte_offset = bit_offset >> 3;
9969
9970         string = tvb_get_ts_23_038_7bits_string(wmem_packet_scope(), tvb, bit_offset, no_of_chars);
9971
9972         if (hfinfo->display == STR_UNICODE) {
9973                 DISSECTOR_ASSERT(g_utf8_validate(string, -1, NULL));
9974         }
9975
9976         pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
9977         DISSECTOR_ASSERT(byte_length >= 0);
9978         proto_tree_set_string(PNODE_FINFO(pi), string);
9979
9980         return pi;
9981 }
9982
9983 proto_item *
9984 proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
9985         const guint bit_offset, const gint no_of_chars)
9986 {
9987         proto_item        *pi;
9988         header_field_info *hfinfo;
9989         gint               byte_length;
9990         gint               byte_offset;
9991         gchar             *string;
9992
9993         CHECK_FOR_NULL_TREE(tree);
9994
9995         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
9996
9997         DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_STRING);
9998
9999         byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
10000         byte_offset = bit_offset >> 3;
10001
10002         string = tvb_get_ascii_7bits_string(wmem_packet_scope(), tvb, bit_offset, no_of_chars);
10003
10004         if (hfinfo->display == STR_UNICODE) {
10005                 DISSECTOR_ASSERT(g_utf8_validate(string, -1, NULL));
10006         }
10007
10008         pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
10009         DISSECTOR_ASSERT(byte_length >= 0);
10010         proto_tree_set_string(PNODE_FINFO(pi), string);
10011
10012         return pi;
10013 }
10014
10015 guchar
10016 proto_check_field_name(const gchar *field_name)
10017 {
10018         return wrs_check_charset(fld_abbrev_chars, field_name);
10019 }
10020
10021 gboolean
10022 tree_expanded(int tree_type)
10023 {
10024         g_assert(tree_type >= 0 && tree_type < num_tree_types);
10025         return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
10026 }
10027
10028 void
10029 tree_expanded_set(int tree_type, gboolean value)
10030 {
10031         g_assert(tree_type >= 0 && tree_type < num_tree_types);
10032
10033         if (value)
10034                 tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
10035         else
10036                 tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
10037 }
10038
10039 /*
10040  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
10041  *
10042  * Local variables:
10043  * c-basic-offset: 8
10044  * tab-width: 8
10045  * indent-tabs-mode: t
10046  * End:
10047  *
10048  * vi: set shiftwidth=8 tabstop=8 noexpandtab:
10049  * :indentSize=8:tabSize=8:noTabs=false:
10050  */