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