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