ed37f560404e154ee9a33ccd0ff58083efa460cb
[metze/wireshark/wip.git] / epan / proto.c
1 /* proto.c
2  * Routines for protocol tree
3  *
4  * $Id$
5  *
6  * Wireshark - Network traffic analyzer
7  * By Gerald Combs <gerald@wireshark.org>
8  * Copyright 1998 Gerald Combs
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
23  */
24
25 #include "config.h"
26
27 #include <stdio.h>
28 #include <string.h>
29 #include <ctype.h>
30 #include <glib.h>
31 #include <float.h>
32
33 #include "packet.h"
34 #include "ptvcursor.h"
35 #include "strutil.h"
36 #include "addr_resolv.h"
37 #include "oids.h"
38 #include "plugins.h"
39 #include "proto.h"
40 #include "epan_dissect.h"
41 #include "tvbuff.h"
42 #include "emem.h"
43 #include "charsets.h"
44 #include "asm_utils.h"
45 #include "column-utils.h"
46 #include "to_str.h"
47 #include "expert.h"
48 #include "show_exception.h"
49
50 #include "wspython/wspy_register.h"
51
52 #define SUBTREE_ONCE_ALLOCATION_NUMBER 8
53 #define SUBTREE_MAX_LEVELS 256
54 /* Throw an exception if we exceed this many tree items. */
55 /* XXX - This should probably be a preference */
56 #define MAX_TREE_ITEMS (1 * 1000 * 1000)
57
58
59 typedef struct __subtree_lvl {
60         gint        cursor_offset;
61         proto_item *it;
62         proto_tree *tree;
63 } subtree_lvl;
64
65 struct ptvcursor {
66         subtree_lvl *pushed_tree;
67         guint8       pushed_tree_index;
68         guint8       pushed_tree_max;
69         proto_tree  *tree;
70         tvbuff_t    *tvb;
71         gint         offset;
72 };
73
74 #define cVALS(x) (const value_string*)(x)
75
76 /** See inlined comments.
77  @param tree the tree to append this item to
78  @param hfindex field index
79  @param hfinfo header_field
80  @return the header field matching 'hfinfo' */
81 #define TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo) \
82         /* If this item is not referenced we dont have to do much work  \
83            at all but we should still return a node so that field items \
84            below this node (think proto_item_add_subtree()) will still  \
85            have somewhere to attach to or else filtering will not work  \
86            (they would be ignored since tree would be NULL).            \
87            DONT try to fake a node where PTREE_FINFO(tree) is NULL      \
88            since dissectors that want to do proto_item_set_len() or     \
89            other operations that dereference this would crash.          \
90            We fake FT_PROTOCOL unless some clients have requested us    \
91            not to do so. \
92         */                                                              \
93         if (!tree)                                                      \
94                 return NULL;                                            \
95         PTREE_DATA(tree)->count++;                                      \
96         if (PTREE_DATA(tree)->count > MAX_TREE_ITEMS) {                 \
97                 if (getenv("WIRESHARK_ABORT_ON_TOO_MANY_ITEMS") != NULL) \
98                         g_error("More than %d items in the tree -- possible infinite loop", MAX_TREE_ITEMS); \
99                 /* Let the exception handler add items to the tree */   \
100                 PTREE_DATA(tree)->count = 0;                            \
101                 THROW_MESSAGE(DissectorError,                           \
102                         ep_strdup_printf("More than %d items in the tree -- possible infinite loop", MAX_TREE_ITEMS)); \
103         }                                                               \
104         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);                       \
105         if (!(PTREE_DATA(tree)->visible)) {                             \
106                 if (PTREE_FINFO(tree)) {                                \
107                         if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT)    \
108                             && (hfinfo->type != FT_PROTOCOL ||          \
109                                 PTREE_DATA(tree)->fake_protocols)) {    \
110                                 /* just return tree back to the caller */\
111                                 return tree;                            \
112                         }                                               \
113                 }                                                       \
114         }
115
116 /** See inlined comments.
117  @param pi the created protocol item we're about to return */
118 #define TRY_TO_FAKE_THIS_REPR(pi) \
119         g_assert(pi);                   \
120         if (!(PTREE_DATA(pi)->visible)) { \
121                 /* If the tree (GUI) isn't visible it's pointless for us to generate the protocol \
122                  * items string representation */ \
123                 return pi; \
124         }
125
126 static const char *hf_try_val_to_str(guint32 value, const header_field_info *hfinfo);
127
128 static void fill_label_boolean(field_info *fi, gchar *label_str);
129 static void fill_label_bitfield(field_info *fi, gchar *label_str);
130 static void fill_label_number(field_info *fi, gchar *label_str, gboolean is_signed);
131 static void fill_label_number64(field_info *fi, gchar *label_str, gboolean is_signed);
132
133 static const char *hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[32], guint32 value);
134 static const char *hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value);
135 static const char *hfinfo_number_value_format(const header_field_info *hfinfo, char buf[32], guint32 value);
136 static const char *hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[32], guint32 value);
137
138 static const char* hfinfo_uint64_format(const header_field_info *hfinfo);
139 static const char* hfinfo_int64_format(const header_field_info *hfinfo);
140
141 static proto_item *
142 proto_tree_add_node(proto_tree *tree, field_info *fi);
143
144 static void
145 get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start, gint *length,
146                 gint *item_length);
147
148 static field_info *
149 new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
150                const gint start, const gint item_length);
151
152 static field_info *
153 alloc_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
154                  const gint start, gint *length);
155
156 static proto_item *
157 proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
158                   gint start, gint *length);
159
160 static void
161 proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap);
162 static void
163 proto_tree_set_representation(proto_item *pi, const char *format, va_list ap);
164
165 static void
166 proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb);
167 static void
168 proto_tree_set_bytes(field_info *fi, const guint8* start_ptr, gint length);
169 static void
170 proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, gint offset, gint length);
171 static void
172 proto_tree_set_time(field_info *fi, nstime_t *value_ptr);
173 static void
174 proto_tree_set_string(field_info *fi, const char* value);
175 static void
176 proto_tree_set_string_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length, gint encoding);
177 static void
178 proto_tree_set_ax25(field_info *fi, const guint8* value);
179 static void
180 proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, gint start);
181 static void
182 proto_tree_set_vines(field_info *fi, const guint8* value);
183 static void
184 proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, gint start);
185 static void
186 proto_tree_set_ether(field_info *fi, const guint8* value);
187 static void
188 proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, gint start);
189 static void
190 proto_tree_set_ipxnet(field_info *fi, guint32 value);
191 static void
192 proto_tree_set_ipv4(field_info *fi, guint32 value);
193 static void
194 proto_tree_set_ipv6(field_info *fi, const guint8* value_ptr);
195 static void
196 proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
197 static void
198 proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr);
199 static void
200 proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, gint start, const guint encoding);
201 static void
202 proto_tree_set_oid(field_info *fi, const guint8* value_ptr, gint length);
203 static void
204 proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
205 static void
206 proto_tree_set_boolean(field_info *fi, guint32 value);
207 static void
208 proto_tree_set_float(field_info *fi, float value);
209 static void
210 proto_tree_set_double(field_info *fi, double value);
211 static void
212 proto_tree_set_uint(field_info *fi, guint32 value);
213 static void
214 proto_tree_set_int(field_info *fi, gint32 value);
215 static void
216 proto_tree_set_uint64(field_info *fi, guint64 value);
217 static void
218 proto_tree_set_uint64_tvb(field_info *fi, tvbuff_t *tvb, gint start, guint length, const guint encoding);
219 static void
220 proto_tree_set_eui64(field_info *fi, const guint64 value);
221 static void
222 proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, gint start, const guint encoding);
223 static gboolean
224 proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
225                             const int len, const gint ett, const gint **fields,
226                             const guint encoding, const int flags,
227                             gboolean first);
228
229 static int proto_register_field_init(header_field_info *hfinfo, const int parent);
230
231 /* special-case header field used within proto.c */
232 static header_field_info hfi_text_only =
233         { "Text item",  "text", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL };
234 int hf_text_only = -1;
235
236 /* Structure for information about a protocol */
237 struct _protocol {
238         const char *name;         /* long description */
239         const char *short_name;   /* short description */
240         const char *filter_name;  /* name of this protocol in filters */
241         int         proto_id;     /* field ID for this protocol */
242         GSList     *fields;       /* fields for this protocol */
243         GSList     *last_field;   /* pointer to end of list of fields */
244         gboolean    is_enabled;   /* TRUE if protocol is enabled */
245         gboolean    can_toggle;   /* TRUE if is_enabled can be changed */
246         gboolean    is_private;   /* TRUE is protocol is private */
247 };
248
249 /* List of all protocols */
250 static GList *protocols = NULL;
251
252 #define INITIAL_NUM_PROTOCOL_HFINFO     1500
253
254 /* Contains information about a field when a dissector calls
255  * proto_tree_add_item.  */
256 #define FIELD_INFO_NEW(fi)  fi = g_slice_new(field_info)
257 #define FIELD_INFO_FREE(fi) g_slice_free(field_info, fi)
258
259 /* Contains the space for proto_nodes. */
260 #define PROTO_NODE_NEW(node)                            \
261         node = g_slice_new(proto_node);                 \
262         node->first_child = NULL;                       \
263         node->last_child = NULL;                        \
264         node->next = NULL;
265
266 #define PROTO_NODE_FREE(node)                           \
267         g_slice_free(proto_node, node)
268
269 /* String space for protocol and field items for the GUI */
270 #define ITEM_LABEL_NEW(il)                              \
271         il = g_slice_new(item_label_t);
272 #define ITEM_LABEL_FREE(il)                             \
273         g_slice_free(item_label_t, il);
274
275 #define PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)                                                \
276         if((guint)hfindex >= gpa_hfinfo.len && getenv("WIRESHARK_ABORT_ON_DISSECTOR_BUG"))      \
277                 g_error("Unregistered hf! index=%d", hfindex);                                  \
278         DISSECTOR_ASSERT_HINT((guint)hfindex < gpa_hfinfo.len, "Unregistered hf!");     \
279         hfinfo = gpa_hfinfo.hfi[hfindex];
280
281 /* List which stores protocols and fields that have been registered */
282 typedef struct _gpa_hfinfo_t {
283         guint32             len;
284         guint32             allocated_len;
285         header_field_info **hfi;
286 } gpa_hfinfo_t;
287
288 static gpa_hfinfo_t gpa_hfinfo;
289
290 /* Balanced tree of abbreviations and IDs */
291 static GTree *gpa_name_tree = NULL;
292 static header_field_info *same_name_hfinfo;
293
294 static void save_same_name_hfinfo(gpointer data)
295 {
296         same_name_hfinfo = (header_field_info*)data;
297 }
298
299 /* Points to the first element of an array of bits, indexed by
300    a subtree item type; that array element is TRUE if subtrees of
301    an item of that type are to be expanded. */
302 static guint32 *tree_is_expanded;
303
304 /* Number of elements in that array. */
305 int             num_tree_types;
306
307 /* Name hashtables for fast detection of duplicate names */
308 static GHashTable* proto_names        = NULL;
309 static GHashTable* proto_short_names  = NULL;
310 static GHashTable* proto_filter_names = NULL;
311
312 static gint
313 proto_compare_name(gconstpointer p1_arg, gconstpointer p2_arg)
314 {
315         const protocol_t *p1 = (const protocol_t *)p1_arg;
316         const protocol_t *p2 = (const protocol_t *)p2_arg;
317
318         return g_ascii_strcasecmp(p1->short_name, p2->short_name);
319 }
320
321
322 /* initialize data structures and register protocols and fields */
323 void
324 proto_init(void (register_all_protocols_func)(register_cb cb, gpointer client_data),
325            void (register_all_handoffs_func)(register_cb cb, gpointer client_data),
326            register_cb cb,
327            gpointer client_data)
328 {
329         proto_cleanup();
330
331         proto_names        = g_hash_table_new_full(g_int_hash, g_int_equal, g_free, NULL);
332         proto_short_names  = g_hash_table_new(wrs_str_hash, g_str_equal);
333         proto_filter_names = g_hash_table_new(wrs_str_hash, g_str_equal);
334
335         gpa_hfinfo.len           = 0;
336         gpa_hfinfo.allocated_len = 0;
337         gpa_hfinfo.hfi           = NULL;
338         gpa_name_tree            = g_tree_new_full(wrs_strcmp_with_data, NULL, NULL, save_same_name_hfinfo);
339
340         /* Initialize the ftype subsystem */
341         ftypes_initialize();
342
343         /* Register one special-case FT_TEXT_ONLY field for use when
344            converting wireshark to new-style proto_tree. These fields
345            are merely strings on the GUI tree; they are not filterable */
346         hf_text_only = proto_register_field_init(&hfi_text_only, -1);
347
348         /* Register the pseudo-protocols used for exceptions. */
349         register_show_exception();
350
351         /* Have each built-in dissector register its protocols, fields,
352            dissector tables, and dissectors to be called through a
353            handle, and do whatever one-time initialization it needs to
354            do. */
355         register_all_protocols_func(cb, client_data);
356 #ifdef HAVE_PYTHON
357         /* Now scan for python protocols */
358         if (cb)
359                 (*cb)(RA_PYTHON_REGISTER, NULL, client_data);
360         register_all_py_protocols_func();
361 #endif
362
363 #ifdef HAVE_PLUGINS
364         /* Now scan for plugins and load all the ones we find, calling
365            their register routines to do the stuff described above. */
366         if (cb)
367                 (*cb)(RA_PLUGIN_REGISTER, NULL, client_data);
368         init_plugins();
369         register_all_plugin_registrations();
370 #endif
371
372         /* Now call the "handoff registration" routines of all built-in
373            dissectors; those routines register the dissector in other
374            dissectors' handoff tables, and fetch any dissector handles
375            they need. */
376         register_all_handoffs_func(cb, client_data);
377
378 #ifdef HAVE_PYTHON
379         /* Now do the same with python dissectors */
380         if (cb)
381                 (*cb)(RA_PYTHON_HANDOFF, NULL, client_data);
382         register_all_py_handoffs_func();
383 #endif
384
385 #ifdef HAVE_PLUGINS
386         /* Now do the same with plugins. */
387         if (cb)
388                 (*cb)(RA_PLUGIN_HANDOFF, NULL, client_data);
389         register_all_plugin_handoffs();
390 #endif
391
392         /* sort the protocols by protocol name */
393         protocols = g_list_sort(protocols, proto_compare_name);
394
395         /* We've assigned all the subtree type values; allocate the array
396            for them, and zero it out. */
397         tree_is_expanded = g_new0(guint32, (num_tree_types/32)+1);
398 }
399
400 void
401 proto_cleanup(void)
402 {
403         /* Free the abbrev/ID GTree */
404         if (gpa_name_tree) {
405                 g_tree_destroy(gpa_name_tree);
406                 gpa_name_tree = NULL;
407         }
408
409         while (protocols) {
410                 protocol_t        *protocol = (protocol_t *)protocols->data;
411                 header_field_info *hfinfo;
412                 PROTO_REGISTRAR_GET_NTH(protocol->proto_id, hfinfo);
413                 DISSECTOR_ASSERT(protocol->proto_id == hfinfo->id);
414
415                 g_slice_free(header_field_info, hfinfo);
416                 g_slist_free(protocol->fields);
417                 protocols = g_list_remove(protocols, protocol);
418                 g_free(protocol);
419         }
420
421         if (proto_names) {
422                 g_hash_table_destroy(proto_names);
423                 proto_names = NULL;
424         }
425
426         if (proto_short_names) {
427                 g_hash_table_destroy(proto_short_names);
428                 proto_short_names = NULL;
429         }
430
431         if (proto_filter_names) {
432                 g_hash_table_destroy(proto_filter_names);
433                 proto_filter_names = NULL;
434         }
435
436         if (gpa_hfinfo.allocated_len) {
437                 gpa_hfinfo.len           = 0;
438                 gpa_hfinfo.allocated_len = 0;
439                 g_free(gpa_hfinfo.hfi);
440                 gpa_hfinfo.hfi           = NULL;
441         }
442         g_free(tree_is_expanded);
443         tree_is_expanded = NULL;
444 }
445
446 static gboolean
447 proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
448                               gpointer data)
449 {
450         proto_node *pnode = tree;
451         proto_node *child;
452         proto_node *current;
453
454         if (func(pnode, data))
455                 return TRUE;
456
457         child = pnode->first_child;
458         while (child != NULL) {
459                 /*
460                  * The routine we call might modify the child, e.g. by
461                  * freeing it, so we get the child's successor before
462                  * calling that routine.
463                  */
464                 current = child;
465                 child   = current->next;
466                 if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
467                         return TRUE;
468         }
469
470         return FALSE;
471 }
472
473 gboolean
474 proto_tree_traverse_post_order(proto_tree *tree, proto_tree_traverse_func func,
475                                gpointer data)
476 {
477         proto_node *pnode = tree;
478         proto_node *child;
479         proto_node *current;
480
481         child = pnode->first_child;
482         while (child != NULL) {
483                 /*
484                  * The routine we call might modify the child, e.g. by
485                  * freeing it, so we get the child's successor before
486                  * calling that routine.
487                  */
488                 current = child;
489                 child   = current->next;
490                 if (proto_tree_traverse_post_order((proto_tree *)current, func, data))
491                         return TRUE;
492         }
493         if (func(pnode, data))
494                 return TRUE;
495
496         return FALSE;
497 }
498
499 void
500 proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
501                             gpointer data)
502 {
503         proto_node *node = tree;
504         proto_node *current;
505
506         if (!node)
507                 return;
508
509         node = node->first_child;
510         while (node != NULL) {
511                 current = node;
512                 node    = current->next;
513                 func((proto_tree *)current, data);
514         }
515 }
516
517 static void
518 free_GPtrArray_value(gpointer key, gpointer value, gpointer user_data _U_)
519 {
520         GPtrArray         *ptrs = (GPtrArray *)value;
521         gint               hfid = (gint)(long)key;
522         header_field_info *hfinfo;
523
524         PROTO_REGISTRAR_GET_NTH(hfid, hfinfo);
525         if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
526                 /* when a field is referenced by a filter this also
527                    affects the refcount for the parent protocol so we need
528                    to adjust the refcount for the parent as well
529                 */
530                 if (hfinfo->parent != -1) {
531                         header_field_info *parent_hfinfo;
532                         PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
533                         parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
534                 }
535                 hfinfo->ref_type = HF_REF_TYPE_NONE;
536         }
537
538         g_ptr_array_free(ptrs, TRUE);
539 }
540
541 static void
542 free_node_tree_data(tree_data_t *tree_data)
543 {
544         if (tree_data->interesting_hfids) {
545                 /* Free all the GPtrArray's in the interesting_hfids hash. */
546                 g_hash_table_foreach(tree_data->interesting_hfids,
547                         free_GPtrArray_value, NULL);
548
549                 /* And then destroy the hash. */
550                 g_hash_table_destroy(tree_data->interesting_hfids);
551         }
552         if (tree_data->fi_tmp)
553                 FIELD_INFO_FREE(tree_data->fi_tmp);
554
555         /* And finally the tree_data_t itself. */
556         g_free(tree_data);
557 }
558
559 #define FREE_NODE_FIELD_INFO(finfo)     \
560         if (finfo->rep) {                       \
561                 ITEM_LABEL_FREE(finfo->rep);    \
562         }                               \
563         FVALUE_CLEANUP(&finfo->value);  \
564         FIELD_INFO_FREE(finfo);
565
566 static void
567 proto_tree_free_node(proto_node *node, gpointer data _U_)
568 {
569         field_info *finfo  = PNODE_FINFO(node);
570
571         proto_tree_children_foreach(node, proto_tree_free_node, NULL);
572
573         /* free the field_info data. */
574         FREE_NODE_FIELD_INFO(finfo);
575         node->finfo = NULL;
576
577         /* Free the proto_node. */
578         PROTO_NODE_FREE(node);
579 }
580
581 /* frees the resources that the dissection a proto_tree uses */
582 void
583 proto_tree_free(proto_tree *tree)
584 {
585         tree_data_t *tree_data = PTREE_DATA(tree);
586
587         proto_tree_children_foreach(tree, proto_tree_free_node, NULL);
588
589         /* free root node */
590         PROTO_NODE_FREE(tree);
591
592         /* free tree data */
593         free_node_tree_data(tree_data);
594 }
595
596 /* Is the parsing being done for a visible proto_tree or an invisible one?
597  * By setting this correctly, the proto_tree creation is sped up by not
598  * having to call g_vsnprintf and copy strings around.
599  */
600 gboolean
601 proto_tree_set_visible(proto_tree *tree, gboolean visible)
602 {
603         gboolean old_visible = PTREE_DATA(tree)->visible;
604
605         PTREE_DATA(tree)->visible = visible;
606
607         return old_visible;
608 }
609
610 void
611 proto_tree_set_fake_protocols(proto_tree *tree, gboolean fake_protocols)
612 {
613         PTREE_DATA(tree)->fake_protocols = fake_protocols;
614 }
615
616 /* Assume dissector set only its protocol fields.
617    This function is called by dissectors and allows the speeding up of filtering
618    in wireshark; if this function returns FALSE it is safe to reset tree to NULL
619    and thus skip calling most of the expensive proto_tree_add_...()
620    functions.
621    If the tree is visible we implicitly assume the field is referenced.
622 */
623 gboolean
624 proto_field_is_referenced(proto_tree *tree, int proto_id)
625 {
626         register header_field_info *hfinfo;
627
628
629         if (!tree)
630                 return FALSE;
631
632         if (PTREE_DATA(tree)->visible)
633                 return TRUE;
634
635         PROTO_REGISTRAR_GET_NTH(proto_id, hfinfo);
636         if (hfinfo->ref_type != HF_REF_TYPE_NONE)
637                 return TRUE;
638
639         if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)->fake_protocols)
640                 return TRUE;
641
642         return FALSE;
643 }
644
645
646 /* Finds a record in the hfinfo array by id. */
647 header_field_info *
648 proto_registrar_get_nth(guint hfindex)
649 {
650         register header_field_info *hfinfo;
651
652         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
653         return hfinfo;
654 }
655
656
657 /*      Prefix initialization
658  *        this allows for a dissector to register a display filter name prefix
659  *        so that it can delay the initialization of the hf array as long as
660  *        possible.
661  */
662
663 /* compute a hash for the part before the dot of a display filter */
664 static guint
665 prefix_hash (gconstpointer key) {
666         /* end the string at the dot and compute its hash */
667         gchar* copy = ep_strdup((const gchar *)key);
668         gchar* c    = copy;
669
670         for (; *c; c++) {
671                 if (*c == '.') {
672                         *c = 0;
673                         break;
674                 }
675         }
676
677         return g_str_hash(copy);
678 }
679
680 /* are both strings equal up to the end or the dot? */
681 static gboolean
682 prefix_equal (gconstpointer ap, gconstpointer bp) {
683         const gchar* a = (const gchar *)ap;
684         const gchar* b = (const gchar *)bp;
685
686         do {
687                 gchar ac = *a++;
688                 gchar bc = *b++;
689
690                 if ( (ac == '.' || ac == '\0') &&   (bc == '.' || bc == '\0') ) return TRUE;
691
692                 if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE;
693                 if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE;
694
695                 if (ac != bc) return FALSE;
696         } while (1);
697
698         return FALSE;
699 }
700
701
702 /* indexed by prefix, contains initializers */
703 static GHashTable* prefixes = NULL;
704
705
706 /* Register a new prefix for "delayed" initialization of field arrays */
707 void
708 proto_register_prefix(const char *prefix, prefix_initializer_t pi ) {
709         if (! prefixes ) {
710                 prefixes = g_hash_table_new(prefix_hash, prefix_equal);
711         }
712
713         g_hash_table_insert(prefixes, (gpointer)prefix, pi);
714 }
715
716 /* helper to call all prefix initializers */
717 static gboolean
718 initialize_prefix(gpointer k, gpointer v, gpointer u _U_) {
719         ((prefix_initializer_t)v)((const char *)k);
720         return TRUE;
721 }
722
723 /** Initialize every remaining uninitialized prefix. */
724 void
725 proto_initialize_all_prefixes(void) {
726         g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL);
727 }
728
729 /* Finds a record in the hfinfo array by name.
730  * If it fails to find it in the already registered fields,
731  * it tries to find and call an initializer in the prefixes
732  * table and if so it looks again.
733  */
734 header_field_info *
735 proto_registrar_get_byname(const char *field_name)
736 {
737         header_field_info    *hfinfo;
738         prefix_initializer_t  pi;
739
740         if (!field_name)
741                 return NULL;
742
743         hfinfo = (header_field_info *)g_tree_lookup(gpa_name_tree, field_name);
744
745         if (hfinfo)
746                 return hfinfo;
747
748         if (!prefixes)
749                 return NULL;
750
751         if ((pi = (prefix_initializer_t)g_hash_table_lookup(prefixes, field_name) ) != NULL) {
752                 pi(field_name);
753                 g_hash_table_remove(prefixes, field_name);
754         } else {
755                 return NULL;
756         }
757
758         return (header_field_info *)g_tree_lookup(gpa_name_tree, field_name);
759 }
760
761 int
762 proto_registrar_get_id_byname(const char *field_name)
763 {
764         header_field_info *hfinfo;
765
766         hfinfo = proto_registrar_get_byname(field_name);
767
768         if (!hfinfo)
769                 return -1;
770
771         return hfinfo->id;
772 }
773
774
775 static void
776 ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
777 {
778         subtree_lvl *pushed_tree;
779
780         DISSECTOR_ASSERT(ptvc->pushed_tree_max <= SUBTREE_MAX_LEVELS-SUBTREE_ONCE_ALLOCATION_NUMBER);
781         ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER;
782
783         pushed_tree = (subtree_lvl *)ep_alloc(sizeof(subtree_lvl) * ptvc->pushed_tree_max);
784         DISSECTOR_ASSERT(pushed_tree != NULL);
785         if (ptvc->pushed_tree)
786                 memcpy(pushed_tree, ptvc->pushed_tree, ptvc->pushed_tree_max - SUBTREE_ONCE_ALLOCATION_NUMBER);
787         ptvc->pushed_tree = pushed_tree;
788 }
789
790 static void
791 ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
792 {
793         ptvc->pushed_tree       = NULL;
794         ptvc->pushed_tree_max   = 0;
795         DISSECTOR_ASSERT(ptvc->pushed_tree_index == 0);
796         ptvc->pushed_tree_index = 0;
797 }
798
799 /* Allocates an initializes a ptvcursor_t with 3 variables:
800  *      proto_tree, tvbuff, and offset. */
801 ptvcursor_t *
802 ptvcursor_new(proto_tree *tree, tvbuff_t *tvb, gint offset)
803 {
804         ptvcursor_t *ptvc;
805
806         ptvc                    = (ptvcursor_t *)ep_alloc(sizeof(ptvcursor_t));
807         ptvc->tree              = tree;
808         ptvc->tvb               = tvb;
809         ptvc->offset            = offset;
810         ptvc->pushed_tree       = NULL;
811         ptvc->pushed_tree_max   = 0;
812         ptvc->pushed_tree_index = 0;
813         return ptvc;
814 }
815
816
817 /* Frees memory for ptvcursor_t, but nothing deeper than that. */
818 void
819 ptvcursor_free(ptvcursor_t *ptvc)
820 {
821         ptvcursor_free_subtree_levels(ptvc);
822         /*g_free(ptvc);*/
823 }
824
825 /* Returns tvbuff. */
826 tvbuff_t *
827 ptvcursor_tvbuff(ptvcursor_t *ptvc)
828 {
829         return ptvc->tvb;
830 }
831
832 /* Returns current offset. */
833 gint
834 ptvcursor_current_offset(ptvcursor_t *ptvc)
835 {
836         return ptvc->offset;
837 }
838
839 proto_tree *
840 ptvcursor_tree(ptvcursor_t *ptvc)
841 {
842         if (!ptvc)
843                 return NULL;
844
845         return ptvc->tree;
846 }
847
848 void
849 ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
850 {
851         ptvc->tree = tree;
852 }
853
854 /* creates a subtree, sets it as the working tree and pushes the old working tree */
855 proto_tree *
856 ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree)
857 {
858         subtree_lvl *subtree;
859         if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
860                 ptvcursor_new_subtree_levels(ptvc);
861
862         subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
863         subtree->tree = ptvc->tree;
864         subtree->it= NULL;
865         ptvc->pushed_tree_index++;
866         return ptvcursor_set_subtree(ptvc, it, ett_subtree);
867 }
868
869 /* pops a subtree */
870 void
871 ptvcursor_pop_subtree(ptvcursor_t *ptvc)
872 {
873         subtree_lvl *subtree;
874
875         if (ptvc->pushed_tree_index <= 0)
876                 return;
877
878         ptvc->pushed_tree_index--;
879         subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
880         if (subtree->it != NULL)
881                 proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
882
883         ptvc->tree = subtree->tree;
884 }
885
886 /* saves the current tvb offset and the item in the current subtree level */
887 static void
888 ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
889 {
890         subtree_lvl *subtree;
891
892         DISSECTOR_ASSERT(ptvc->pushed_tree_index > 0);
893
894         subtree                = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
895         subtree->it            = it;
896         subtree->cursor_offset = ptvcursor_current_offset(ptvc);
897 }
898
899 /* Creates a subtree and adds it to the cursor as the working tree but does not
900  * save the old working tree */
901 proto_tree *
902 ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree)
903 {
904         ptvc->tree = proto_item_add_subtree(it, ett_subtree);
905         return ptvc->tree;
906 }
907
908 static proto_tree *
909 ptvcursor_add_subtree_item(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree, gint length)
910 {
911         ptvcursor_push_subtree(ptvc, it, ett_subtree);
912         if (length == SUBTREE_UNDEFINED_LENGTH)
913                 ptvcursor_subtree_set_item(ptvc, it);
914         return ptvcursor_tree(ptvc);
915 }
916
917 /* Add an item to the tree and create a subtree
918  * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
919  * In this case, when the subtree will be closed, the parent item length will
920  * be equal to the advancement of the cursor since the creation of the subtree.
921  */
922 proto_tree *
923 ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, gint length,
924                            const guint encoding, gint ett_subtree)
925 {
926         proto_item *it;
927
928         it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
929         return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
930 }
931
932 static proto_item *
933 proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, gint start, gint length);
934
935 /* Add a text node to the tree and create a subtree
936  * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
937  * In this case, when the subtree will be closed, the item length will be equal
938  * to the advancement of the cursor since the creation of the subtree.
939  */
940 proto_tree *
941 ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, gint length,
942                                 gint ett_subtree, const char *format, ...)
943 {
944         proto_item        *pi;
945         va_list            ap;
946         header_field_info *hfinfo;
947         proto_tree        *tree;
948
949         tree = ptvcursor_tree(ptvc);
950
951         TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
952
953         pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
954                                       ptvcursor_current_offset(ptvc), length);
955
956         TRY_TO_FAKE_THIS_REPR(pi);
957
958         va_start(ap, format);
959         proto_tree_set_representation(pi, format, ap);
960         va_end(ap);
961
962         return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
963 }
964
965 /* Add a text-only node, leaving it to our caller to fill the text in */
966 static proto_item *
967 proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, gint start, gint length)
968 {
969         proto_item *pi;
970
971         if (tree == NULL)
972                 return NULL;
973
974         pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
975
976         return pi;
977 }
978
979 /* Add a text-only node to the proto_tree */
980 proto_item *
981 proto_tree_add_text(proto_tree *tree, tvbuff_t *tvb, gint start, gint length,
982                     const char *format, ...)
983 {
984         proto_item        *pi;
985         va_list            ap;
986         header_field_info *hfinfo;
987
988         TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
989
990         pi = proto_tree_add_text_node(tree, tvb, start, length);
991
992         TRY_TO_FAKE_THIS_REPR(pi);
993
994         va_start(ap, format);
995         proto_tree_set_representation(pi, format, ap);
996         va_end(ap);
997
998         return pi;
999 }
1000
1001 /* Add a text-only node to the proto_tree (va_list version) */
1002 proto_item *
1003 proto_tree_add_text_valist(proto_tree *tree, tvbuff_t *tvb, gint start,
1004                            gint length, const char *format, va_list ap)
1005 {
1006         proto_item        *pi;
1007         header_field_info *hfinfo;
1008
1009         TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1010
1011         pi = proto_tree_add_text_node(tree, tvb, start, length);
1012
1013         TRY_TO_FAKE_THIS_REPR(pi);
1014
1015         proto_tree_set_representation(pi, format, ap);
1016
1017         return pi;
1018 }
1019
1020 /* Add a text-only node for debugging purposes. The caller doesn't need
1021  * to worry about tvbuff, start, or length. Debug message gets sent to
1022  * STDOUT, too */
1023 proto_item *
1024 proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
1025 {
1026         proto_item *pi;
1027         va_list     ap;
1028
1029         pi = proto_tree_add_text_node(tree, NULL, 0, 0);
1030
1031         if (pi) {
1032                 va_start(ap, format);
1033                 proto_tree_set_representation(pi, format, ap);
1034                 va_end(ap);
1035         }
1036         va_start(ap, format);
1037         vprintf(format, ap);
1038         va_end(ap);
1039         printf("\n");
1040
1041         return pi;
1042 }
1043
1044 /* We could probably get away with changing is_error to a minimum length value. */
1045 static void
1046 report_type_length_mismatch(proto_tree *tree, const gchar *descr, int length, gboolean is_error) {
1047         if (tree) {
1048                 tree_data_t *tree_data = PTREE_DATA(tree);
1049                 field_info *fi_save = tree_data->fi_tmp;
1050
1051                 /* Keep the current item from getting freed by proto_tree_new_item. */
1052                 tree_data->fi_tmp = NULL;
1053
1054                 expert_add_info_format(NULL, tree, PI_MALFORMED, is_error ? PI_ERROR : PI_WARN, "Trying to fetch %s with length %d", descr, length);
1055
1056                 tree_data->fi_tmp = fi_save;
1057         }
1058
1059         if (is_error) {
1060                 THROW(ReportedBoundsError);
1061         }
1062 }
1063
1064 static guint32
1065 get_uint_value(proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, const guint encoding)
1066 {
1067         guint32 value;
1068         gboolean length_error;
1069
1070         switch (length) {
1071
1072         case 1:
1073                 value = tvb_get_guint8(tvb, offset);
1074                 break;
1075
1076         case 2:
1077                 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohs(tvb, offset)
1078                                                        : tvb_get_ntohs(tvb, offset);
1079                 break;
1080
1081         case 3:
1082                 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh24(tvb, offset)
1083                                                        : tvb_get_ntoh24(tvb, offset);
1084                 break;
1085
1086         case 4:
1087                 value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohl(tvb, offset)
1088                                                        : tvb_get_ntohl(tvb, offset);
1089                 break;
1090
1091         default:
1092                 if (length < 1) {
1093                         length_error = TRUE;
1094                         value = 0;
1095                 } else {
1096                         length_error = FALSE;
1097                         value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohl(tvb, offset)
1098                                                                : tvb_get_ntohl(tvb, offset);
1099                 }
1100                 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1101                 break;
1102         }
1103         return value;
1104 }
1105
1106 /*
1107  * NOTE: to support code written when proto_tree_add_item() took a
1108  * gboolean as its last argument, with FALSE meaning "big-endian"
1109  * and TRUE meaning "little-endian", we treat any non-zero value of
1110  * "encoding" as meaning "little-endian".
1111  */
1112 static gint32
1113 get_int_value(proto_tree *tree, tvbuff_t *tvb, gint offset, gint length, const guint encoding)
1114 {
1115         gint32 value;
1116         gboolean length_error;
1117
1118         switch (length) {
1119
1120         case 1:
1121                 value = (gint8)tvb_get_guint8(tvb, offset);
1122                 break;
1123
1124         case 2:
1125                 value = (gint16) (encoding ? tvb_get_letohs(tvb, offset)
1126                                            : tvb_get_ntohs(tvb, offset));
1127                 break;
1128
1129         case 3:
1130                 value = encoding ? tvb_get_letoh24(tvb, offset)
1131                                  : tvb_get_ntoh24(tvb, offset);
1132                 if (value & 0x00800000) {
1133                         /* Sign bit is set; sign-extend it. */
1134                         value |= 0xFF000000;
1135                 }
1136                 break;
1137
1138         case 4:
1139                 value = encoding ? tvb_get_letohl(tvb, offset)
1140                                  : tvb_get_ntohl(tvb, offset);
1141                 break;
1142
1143         default:
1144                 if (length < 1) {
1145                         length_error = TRUE;
1146                         value = 0;
1147                 } else {
1148                         length_error = FALSE;
1149                         value = encoding ? tvb_get_letohl(tvb, offset)
1150                                          : tvb_get_ntohl(tvb, offset);
1151                 }
1152                 report_type_length_mismatch(tree, "a signed integer", length, length_error);
1153                 break;
1154         }
1155         return value;
1156 }
1157
1158 static void
1159 tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
1160 {
1161         const header_field_info *hfinfo = fi->hfinfo;
1162
1163         if (hfinfo->ref_type == HF_REF_TYPE_DIRECT) {
1164                 GPtrArray *ptrs = NULL;
1165
1166                 if (tree_data->interesting_hfids == NULL) {
1167                         /* Initialize the hash because we now know that it is needed */
1168                         tree_data->interesting_hfids =
1169                                 g_hash_table_new(g_direct_hash, NULL /* g_direct_equal */);
1170                 } else
1171                         ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
1172                                            GINT_TO_POINTER(hfinfo->id));
1173                 if (!ptrs) {
1174                         /* First element triggers the creation of pointer array */
1175                         ptrs = g_ptr_array_new();
1176                         g_hash_table_insert(tree_data->interesting_hfids,
1177                                             GINT_TO_POINTER(hfinfo->id), ptrs);
1178                 }
1179
1180                 g_ptr_array_add(ptrs, fi);
1181         }
1182 }
1183
1184 /* Add an item to a proto_tree, using the text label registered to that item;
1185    the item is extracted from the tvbuff handed to it. */
1186 static proto_item *
1187 proto_tree_new_item(field_info *new_fi, proto_tree *tree,
1188                     tvbuff_t *tvb, gint start, gint length,
1189                     guint encoding)
1190 {
1191         tree_data_t *tree_data = PTREE_DATA(tree);
1192         proto_item *pi;
1193         guint32     value, n;
1194         float       floatval;
1195         double      doubleval;
1196         const char *string;
1197         nstime_t    time_stamp;
1198         guint32     tmpsecs;
1199         gboolean    length_error;
1200
1201         /* there is a possibility here that we might raise an exception
1202          * and thus would lose track of the field_info.
1203          * store it in a temp so that if we come here again we can reclaim
1204          * the field_info without leaking memory.
1205          */
1206         if (tree_data->fi_tmp) {
1207                 /* oops, last one we got must have been lost due
1208                  * to an exception.
1209                  * good thing we saved it, now we can reverse the
1210                  * memory leak and reclaim it.
1211                  */
1212                 FIELD_INFO_FREE(tree_data->fi_tmp);
1213         }
1214         /* we might throw an exception, keep track of this one
1215          * across the "dangerous" section below.
1216         */
1217         tree_data->fi_tmp = new_fi;
1218
1219         switch (new_fi->hfinfo->type) {
1220                 case FT_NONE:
1221                         /* no value to set for FT_NONE */
1222                         break;
1223
1224                 case FT_PROTOCOL:
1225                         proto_tree_set_protocol_tvb(new_fi, tvb);
1226                         break;
1227
1228                 case FT_BYTES:
1229                         proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
1230                         break;
1231
1232                 case FT_UINT_BYTES:
1233                         /*
1234                          * Map all non-zero values to little-endian for
1235                          * backwards compatibility.
1236                          */
1237                         if (encoding)
1238                                 encoding = ENC_LITTLE_ENDIAN;
1239                         n = get_uint_value(tree, tvb, start, length, encoding);
1240                         proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
1241
1242                         /* Instead of calling proto_item_set_len(), since we don't yet
1243                          * have a proto_item, we set the field_info's length ourselves. */
1244                         new_fi->length = n + length;
1245                         break;
1246
1247                 case FT_BOOLEAN:
1248                         /*
1249                          * Map all non-zero values to little-endian for
1250                          * backwards compatibility.
1251                          */
1252                         if (encoding)
1253                                 encoding = ENC_LITTLE_ENDIAN;
1254                         proto_tree_set_boolean(new_fi,
1255                                 get_uint_value(tree, tvb, start, length, encoding));
1256                         break;
1257
1258                 /* XXX - make these just FT_UINT? */
1259                 case FT_UINT8:
1260                 case FT_UINT16:
1261                 case FT_UINT24:
1262                 case FT_UINT32:
1263                         /*
1264                          * Map all non-zero values to little-endian for
1265                          * backwards compatibility.
1266                          */
1267                         if (encoding)
1268                                 encoding = ENC_LITTLE_ENDIAN;
1269                         proto_tree_set_uint(new_fi,
1270                                 get_uint_value(tree, tvb, start, length, encoding));
1271                         break;
1272
1273                 case FT_INT64:
1274                 case FT_UINT64:
1275                         /*
1276                          * Map all non-zero values to little-endian for
1277                          * backwards compatibility.
1278                          */
1279                         if (encoding)
1280                                 encoding = ENC_LITTLE_ENDIAN;
1281                         if (length < 1 || length > 8) {
1282                                 length_error = length < 1 ? TRUE : FALSE;
1283                                 report_type_length_mismatch(tree, "a 64-bit integer", length, length_error);
1284                         }
1285                         proto_tree_set_uint64_tvb(new_fi, tvb, start, length, encoding);
1286                         break;
1287
1288                 /* XXX - make these just FT_INT? */
1289                 case FT_INT8:
1290                 case FT_INT16:
1291                 case FT_INT24:
1292                 case FT_INT32:
1293                         /*
1294                          * Map all non-zero values to little-endian for
1295                          * backwards compatibility.
1296                          */
1297                         if (encoding)
1298                                 encoding = ENC_LITTLE_ENDIAN;
1299                         proto_tree_set_int(new_fi,
1300                                 get_int_value(tree, tvb, start, length, encoding));
1301                         break;
1302
1303                 case FT_IPv4:
1304                         /*
1305                          * Map all non-zero values to little-endian for
1306                          * backwards compatibility.
1307                          */
1308                         if (encoding)
1309                                 encoding = ENC_LITTLE_ENDIAN;
1310                         if (length != FT_IPv4_LEN) {
1311                                 length_error = length < FT_IPv4_LEN ? TRUE : FALSE;
1312                                 report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
1313                         }
1314                         value = tvb_get_ipv4(tvb, start);
1315                         /*
1316                          * NOTE: to support code written when
1317                          * proto_tree_add_item() took a gboolean as its
1318                          * last argument, with FALSE meaning "big-endian"
1319                          * and TRUE meaning "little-endian", we treat any
1320                          * non-zero value of "encoding" as meaning
1321                          * "little-endian".
1322                          */
1323                         proto_tree_set_ipv4(new_fi, encoding ? GUINT32_SWAP_LE_BE(value) : value);
1324                         break;
1325
1326                 case FT_IPXNET:
1327                         if (length != FT_IPXNET_LEN) {
1328                                 length_error = length < FT_IPXNET_LEN ? TRUE : FALSE;
1329                                 report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
1330                         }
1331                         proto_tree_set_ipxnet(new_fi,
1332                                 get_uint_value(tree, tvb, start, FT_IPXNET_LEN, ENC_BIG_ENDIAN));
1333                         break;
1334
1335                 case FT_IPv6:
1336                         if (length != FT_IPv6_LEN) {
1337                                 length_error = length < FT_IPv6_LEN ? TRUE : FALSE;
1338                                 report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
1339                         }
1340                         proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
1341                         break;
1342
1343                 case FT_AX25:
1344                         if (length != 7) {
1345                                 length_error = length < 7 ? TRUE : FALSE;
1346                                 report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
1347                         }
1348                         proto_tree_set_ax25_tvb(new_fi, tvb, start);
1349                         break;
1350
1351                 case FT_VINES:
1352                         if (length != VINES_ADDR_LEN) {
1353                                 length_error = length < VINES_ADDR_LEN ? TRUE : FALSE;
1354                                 report_type_length_mismatch(tree, "a Vines address", length, length_error);
1355                         }
1356                         proto_tree_set_vines_tvb(new_fi, tvb, start);
1357                         break;
1358
1359                 case FT_ETHER:
1360                         if (length != FT_ETHER_LEN) {
1361                                 length_error = length < FT_ETHER_LEN ? TRUE : FALSE;
1362                                 report_type_length_mismatch(tree, "an Ethernet", length, length_error);
1363                         }
1364                         proto_tree_set_ether_tvb(new_fi, tvb, start);
1365                         break;
1366
1367                 case FT_EUI64:
1368                         /*
1369                          * Map all non-zero values to little-endian for
1370                          * backwards compatibility.
1371                          */
1372                         if (encoding)
1373                                 encoding = ENC_LITTLE_ENDIAN;
1374                         if (length != FT_EUI64_LEN) {
1375                                 length_error = length < FT_EUI64_LEN ? TRUE : FALSE;
1376                                 report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
1377                         }
1378                         proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
1379                         break;
1380                 case FT_GUID:
1381                         /*
1382                          * Map all non-zero values to little-endian for
1383                          * backwards compatibility.
1384                          */
1385                         if (encoding)
1386                                 encoding = ENC_LITTLE_ENDIAN;
1387                         if (length != FT_GUID_LEN) {
1388                                 length_error = length < FT_GUID_LEN ? TRUE : FALSE;
1389                                 report_type_length_mismatch(tree, "a GUID", length, length_error);
1390                         }
1391                         proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
1392                         break;
1393
1394                 case FT_OID:
1395                         proto_tree_set_oid_tvb(new_fi, tvb, start, length);
1396                         break;
1397
1398                 case FT_FLOAT:
1399                         /*
1400                          * NOTE: to support code written when
1401                          * proto_tree_add_item() took a gboolean as its
1402                          * last argument, with FALSE meaning "big-endian"
1403                          * and TRUE meaning "little-endian", we treat any
1404                          * non-zero value of "encoding" as meaning
1405                          * "little-endian".
1406                          *
1407                          * At some point in the future, we might
1408                          * support non-IEEE-binary floating-point
1409                          * formats in the encoding as well
1410                          * (IEEE decimal, System/3x0, VAX).
1411                          */
1412                         if (encoding)
1413                                 encoding = ENC_LITTLE_ENDIAN;
1414                         if (length != 4) {
1415                                 length_error = length < 4 ? TRUE : FALSE;
1416                                 report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
1417                         }
1418                         if (encoding)
1419                                 floatval = tvb_get_letohieee_float(tvb, start);
1420                         else
1421                                 floatval = tvb_get_ntohieee_float(tvb, start);
1422                         proto_tree_set_float(new_fi, floatval);
1423                         break;
1424
1425                 case FT_DOUBLE:
1426                         /*
1427                          * NOTE: to support code written when
1428                          * proto_tree_add_item() took a gboolean as its
1429                          * last argument, with FALSE meaning "big-endian"
1430                          * and TRUE meaning "little-endian", we treat any
1431                          * non-zero value of "encoding" as meaning
1432                          * "little-endian".
1433                          *
1434                          * At some point in the future, we might
1435                          * support non-IEEE-binary floating-point
1436                          * formats in the encoding as well
1437                          * (IEEE decimal, System/3x0, VAX).
1438                          */
1439                         if (encoding == TRUE)
1440                                 encoding = ENC_LITTLE_ENDIAN;
1441                         if (length != 8) {
1442                                 length_error = length < 8 ? TRUE : FALSE;
1443                                 report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
1444                         }
1445                         if (encoding)
1446                                 doubleval = tvb_get_letohieee_double(tvb, start);
1447                         else
1448                                 doubleval = tvb_get_ntohieee_double(tvb, start);
1449                         proto_tree_set_double(new_fi, doubleval);
1450                         break;
1451
1452                 case FT_STRING:
1453                         proto_tree_set_string_tvb(new_fi, tvb, start, length,
1454                             encoding);
1455                         break;
1456
1457                 case FT_STRINGZ:
1458                         if (length < -1 ) {
1459                                 report_type_length_mismatch(tree, "a string", length, TRUE);
1460                         }
1461                         /* Instead of calling proto_item_set_len(),
1462                          * since we don't yet have a proto_item, we
1463                          * set the field_info's length ourselves.
1464                          *
1465                          * XXX - our caller can't use that length to
1466                          * advance an offset unless they arrange that
1467                          * there always be a protocol tree into which
1468                          * we're putting this item.
1469                          */
1470                         if (length == -1) {
1471                                 /* This can throw an exception */
1472                                 string = tvb_get_stringz_enc(tvb, start, &length, encoding);
1473                         } else if (length == 0) {
1474                                 string = "[Empty]";
1475                         } else {
1476                                 /* In this case, length signifies
1477                                  * the length of the string.
1478                                  *
1479                                  * This could either be a null-padded
1480                                  * string, which doesn't necessarily
1481                                  * have a '\0' at the end, or a
1482                                  * null-terminated string, with a
1483                                  * trailing '\0'.  (Yes, there are
1484                                  * cases where you have a string
1485                                  * that's both counted and null-
1486                                  * terminated.)
1487                                  *
1488                                  * In the first case, we must
1489                                  * allocate a buffer of length
1490                                  * "length+1", to make room for
1491                                  * a trailing '\0'.
1492                                  *
1493                                  * In the second case, we don't
1494                                  * assume that there is a trailing
1495                                  * '\0' there, as the packet might
1496                                  * be malformed.  (XXX - should we
1497                                  * throw an exception if there's no
1498                                  * trailing '\0'?)      Therefore, we
1499                                  * allocate a buffer of length
1500                                  * "length+1", and put in a trailing
1501                                  * '\0', just to be safe.
1502                                  *
1503                                  * (XXX - this would change if
1504                                  * we made string values counted
1505                                  * rather than null-terminated.)
1506                                  */
1507                                 string = tvb_get_ephemeral_string_enc(tvb, start, length, encoding);
1508                         }
1509                         new_fi->length = length;
1510                         proto_tree_set_string(new_fi, string);
1511                         break;
1512
1513                 case FT_UINT_STRING:
1514                         /*
1515                          * NOTE: to support code written when
1516                          * proto_tree_add_item() took a gboolean as its
1517                          * last argument, with FALSE meaning "big-endian"
1518                          * and TRUE meaning "little-endian", if the
1519                          * encoding value is TRUE, treat that as
1520                          * ASCII with a little-endian length.
1521                          *
1522                          * This won't work for code that passes
1523                          * arbitrary non-zero values; that code
1524                          * will need to be fixed.
1525                          */
1526                         if (encoding == TRUE)
1527                                 encoding = ENC_ASCII|ENC_LITTLE_ENDIAN;
1528                         n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK);
1529                         proto_tree_set_string_tvb(new_fi, tvb, start + length, n,
1530                             encoding);
1531
1532                         /* Instead of calling proto_item_set_len(), since we
1533                          * don't yet have a proto_item, we set the
1534                          * field_info's length ourselves.
1535                          *
1536                          * XXX - our caller can't use that length to
1537                          * advance an offset unless they arrange that
1538                          * there always be a protocol tree into which
1539                          * we're putting this item.
1540                          */
1541                         new_fi->length = n + length;
1542                         break;
1543
1544                 case FT_ABSOLUTE_TIME:
1545                         /*
1546                          * Absolute times can be in any of a number of
1547                          * formats, and they can be big-endian or
1548                          * little-endian.
1549                          *
1550                          * Historically FT_TIMEs were only timespecs;
1551                          * the only question was whether they were stored
1552                          * in big- or little-endian format.
1553                          *
1554                          * For backwards compatibility, we interpret an
1555                          * encoding of 1 as meaning "little-endian timespec",
1556                          * so that passing TRUE is interpreted as that.
1557                          */
1558                         if (encoding == TRUE)
1559                                 encoding = ENC_TIME_TIMESPEC|ENC_LITTLE_ENDIAN;
1560
1561                         if (length != 8 && length != 4) {
1562                                 length_error = length < 4 ? TRUE : FALSE;
1563                                 report_type_length_mismatch(tree, "an absolute time value", length, length_error);
1564                         }
1565
1566                         switch (encoding) {
1567
1568                         case ENC_TIME_TIMESPEC|ENC_BIG_ENDIAN:
1569                                 /*
1570                                  * 4-byte UNIX epoch, possibly followed by
1571                                  * 4-byte fractional time in nanoseconds,
1572                                  * both big-endian.
1573                                  */
1574                                 time_stamp.secs  = tvb_get_ntohl(tvb, start);
1575                                 if (length == 8)
1576                                         time_stamp.nsecs = tvb_get_ntohl(tvb, start+4);
1577                                 else
1578                                         time_stamp.nsecs = 0;
1579                                 break;
1580
1581                         case ENC_TIME_TIMESPEC|ENC_LITTLE_ENDIAN:
1582                                 /*
1583                                  * 4-byte UNIX epoch, possibly followed by
1584                                  * 4-byte fractional time in nanoseconds,
1585                                  * both little-endian.
1586                                  */
1587                                 time_stamp.secs  = tvb_get_letohl(tvb, start);
1588                                 if (length == 8)
1589                                         time_stamp.nsecs = tvb_get_letohl(tvb, start+4);
1590                                 else
1591                                         time_stamp.nsecs = 0;
1592                                 break;
1593
1594                         case ENC_TIME_NTP|ENC_BIG_ENDIAN:
1595                                 /*
1596                                  * NTP time stamp, big-endian.
1597                                  */
1598
1599 /* XXX - where should this go? */
1600 #define NTP_BASETIME 2208988800ul
1601
1602                                 /* We need a temporary variable here so the unsigned math
1603                                  * works correctly (for years > 2036 according to RFC 2030
1604                                  * chapter 3).
1605                                  */
1606                                 tmpsecs  = tvb_get_ntohl(tvb, start);
1607                                 if (tmpsecs)
1608                                         time_stamp.secs = tmpsecs - (guint32)NTP_BASETIME;
1609                                 else
1610                                         time_stamp.secs = tmpsecs; /* 0 */
1611
1612                                 if (length == 8) {
1613                                         /*
1614                                          * We're using nanoseconds here (and we will
1615                                          * display nanoseconds), but NTP's timestamps
1616                                          * have a precision in microseconds or greater.
1617                                          * Round to 1 microsecond.
1618                                          */
1619                                         time_stamp.nsecs = (int)(1000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
1620                                         time_stamp.nsecs *= 1000;
1621                                 } else {
1622                                         time_stamp.nsecs = 0;
1623                                 }
1624                                 break;
1625
1626                         case ENC_TIME_NTP|ENC_LITTLE_ENDIAN:
1627                                 /*
1628                                  * NTP time stamp, big-endian.
1629                                  */
1630                                 tmpsecs  = tvb_get_letohl(tvb, start);
1631                                 if (tmpsecs)
1632                                         time_stamp.secs = tmpsecs - (guint32)NTP_BASETIME;
1633                                 else
1634                                         time_stamp.secs = tmpsecs; /* 0 */
1635
1636                                 if (length == 8) {
1637                                         /*
1638                                          * We're using nanoseconds here (and we will
1639                                          * display nanoseconds), but NTP's timestamps
1640                                          * have a precision in microseconds or greater.
1641                                          * Round to 1 microsecond.
1642                                          */
1643                                         time_stamp.nsecs = (int)(1000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
1644                                         time_stamp.nsecs *= 1000;
1645                                 } else {
1646                                         time_stamp.nsecs = 0;
1647                                 }
1648                                 break;
1649
1650                         default:
1651                                 DISSECTOR_ASSERT_NOT_REACHED();
1652                                 time_stamp.secs = 0;
1653                                 time_stamp.nsecs = 0;
1654                                 break;
1655                         }
1656                         proto_tree_set_time(new_fi, &time_stamp);
1657                         break;
1658
1659                 case FT_RELATIVE_TIME:
1660                         /*
1661                          * Relative times can be in any of a number of
1662                          * formats, and they can be big-endian or
1663                          * little-endian.
1664                          *
1665                          * Historically FT_TIMEs were only timespecs;
1666                          * the only question was whether they were stored
1667                          * in big- or little-endian format.
1668                          *
1669                          * For backwards compatibility, we interpret an
1670                          * encoding of 1 as meaning "little-endian timespec",
1671                          * so that passing TRUE is interpreted as that.
1672                          */
1673                         if (encoding == TRUE)
1674                                 encoding = ENC_TIME_TIMESPEC|ENC_LITTLE_ENDIAN;
1675                         switch (encoding) {
1676
1677                         if (length != 8 && length != 4) {
1678                                 length_error = length < 4 ? TRUE : FALSE;
1679                                 report_type_length_mismatch(tree, "a relative time value", length, length_error);
1680                         }
1681
1682                         case ENC_TIME_TIMESPEC|ENC_BIG_ENDIAN:
1683                                 /*
1684                                  * 4-byte UNIX epoch, possibly followed by
1685                                  * 4-byte fractional time in nanoseconds,
1686                                  * both big-endian.
1687                                  */
1688                                 time_stamp.secs  = tvb_get_ntohl(tvb, start);
1689                                 if (length == 8)
1690                                         time_stamp.nsecs = tvb_get_ntohl(tvb, start+4);
1691                                 else
1692                                         time_stamp.nsecs = 0;
1693                                 break;
1694
1695                         case ENC_TIME_TIMESPEC|ENC_LITTLE_ENDIAN:
1696                                 /*
1697                                  * 4-byte UNIX epoch, possibly followed by
1698                                  * 4-byte fractional time in nanoseconds,
1699                                  * both little-endian.
1700                                  */
1701                                 time_stamp.secs  = tvb_get_letohl(tvb, start);
1702                                 if (length == 8)
1703                                         time_stamp.nsecs = tvb_get_letohl(tvb, start+4);
1704                                 else
1705                                         time_stamp.nsecs = 0;
1706                                 break;
1707                         }
1708                         proto_tree_set_time(new_fi, &time_stamp);
1709                         break;
1710
1711                 default:
1712                         g_error("new_fi->hfinfo->type %d (%s) not handled\n",
1713                                         new_fi->hfinfo->type,
1714                                         ftype_name(new_fi->hfinfo->type));
1715                         DISSECTOR_ASSERT_NOT_REACHED();
1716                         break;
1717         }
1718         FI_SET_FLAG(new_fi, (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN);
1719
1720         /* Don't add new node to proto_tree until now so that any exceptions
1721          * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
1722         /* XXX. wouldn't be better to add this item to tree, with some special flag (FI_EXCEPTION?)
1723          *      to know which item caused exception? */
1724         pi = proto_tree_add_node(tree, new_fi);
1725
1726         /* we did not raise an exception so we dont have to remember this
1727          * field_info struct any more.
1728          */
1729         tree_data->fi_tmp = NULL;
1730
1731         return pi;
1732 }
1733
1734 /* Gets data from tvbuff, adds it to proto_tree, increments offset,
1735    and returns proto_item* */
1736 proto_item *
1737 ptvcursor_add(ptvcursor_t *ptvc, int hfindex, gint length,
1738               const guint encoding)
1739 {
1740         field_info        *new_fi;
1741         header_field_info *hfinfo;
1742         gint               item_length;
1743         guint32            n;
1744         int                offset;
1745
1746         /* We can't fake it just yet. We have to advance the cursor
1747         TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo); */
1748
1749         offset = ptvc->offset;
1750         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
1751         get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length);
1752         ptvc->offset += length;
1753         if (hfinfo->type == FT_UINT_BYTES || hfinfo->type == FT_UINT_STRING) {
1754                 /*
1755                  * The length of the rest of the item is in the first N
1756                  * bytes of the item.
1757                  */
1758                 n = get_uint_value(ptvc->tree, ptvc->tvb, offset, length, encoding);
1759                 ptvc->offset += n;
1760         }
1761
1762         /* Coast clear. Try and fake it */
1763         TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo);
1764
1765         new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
1766
1767         return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
1768                 offset, length, encoding);
1769 }
1770
1771 /*
1772  * Validates that field length bytes are available starting from
1773  * start (pos/neg). Throws an exception if they aren't.
1774  */
1775 static void
1776 test_length(header_field_info *hfinfo, proto_tree *tree, tvbuff_t *tvb,
1777             gint start, gint length, const guint encoding)
1778 {
1779         gint size = length;
1780
1781         if (!tvb)
1782                 return;
1783
1784         if (hfinfo->type == FT_UINT_BYTES || hfinfo->type == FT_UINT_STRING) {
1785                 guint32 n;
1786
1787                 n = get_uint_value(tree, tvb, start, length, encoding);
1788                 if (n > size + n) {
1789                         /* If n > size + n then we have an integer overflow, so
1790                          * set size to -1, which will force the
1791                          * tvb_ensure_bytes_exist call below to throw a
1792                          * ReportedBoundsError
1793                          */
1794                         size = -1;
1795                 }
1796                 else {
1797                         size += n;
1798                 }
1799         } else if (hfinfo->type == FT_STRINGZ) {
1800                 /* If we're fetching until the end of the TVB, only validate
1801                  * that the offset is within range.
1802                  */
1803                 if (length == -1)
1804                         size = 0;
1805         }
1806
1807         tvb_ensure_bytes_exist(tvb, start, size);
1808 }
1809
1810 /* Add an item to a proto_tree, using the text label registered to that item;
1811    the item is extracted from the tvbuff handed to it. */
1812 proto_item *
1813 proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
1814                     const gint start, gint length, const guint encoding)
1815 {
1816         field_info        *new_fi;
1817         gint              item_length;
1818
1819         DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
1820
1821         get_hfi_length(hfinfo, tvb, start, &length, &item_length);
1822         test_length(hfinfo, tree, tvb, start, item_length, encoding);
1823
1824         TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
1825
1826         new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
1827
1828         if (new_fi == NULL)
1829                 return NULL;
1830
1831         return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
1832 }
1833
1834 proto_item *
1835 proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
1836                     const gint start, gint length, const guint encoding)
1837 {
1838         return proto_tree_add_item_new(tree, proto_registrar_get_nth(hfindex), tvb, start, length, encoding);
1839 }
1840
1841 /* Add a FT_NONE to a proto_tree */
1842 proto_item *
1843 proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
1844                            const gint start, gint length, const char *format,
1845                            ...)
1846 {
1847         proto_item        *pi;
1848         va_list            ap;
1849         header_field_info *hfinfo;
1850
1851         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
1852
1853         DISSECTOR_ASSERT(hfinfo->type == FT_NONE);
1854
1855         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
1856
1857         TRY_TO_FAKE_THIS_REPR(pi);
1858
1859         va_start(ap, format);
1860         proto_tree_set_representation(pi, format, ap);
1861         va_end(ap);
1862
1863         /* no value to set for FT_NONE */
1864         return pi;
1865 }
1866
1867 /* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
1868  * offset, and returns proto_item* */
1869 proto_item *
1870 ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, gint length,
1871                          const guint encoding)
1872 {
1873         proto_item *item;
1874
1875         item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
1876                                    length, encoding);
1877
1878         return item;
1879 }
1880
1881 /* Advance the ptvcursor's offset within its tvbuff without
1882  * adding anything to the proto_tree. */
1883 void
1884 ptvcursor_advance(ptvcursor_t* ptvc, gint length)
1885 {
1886         ptvc->offset += length;
1887 }
1888
1889
1890 static void
1891 proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb)
1892 {
1893         fvalue_set(&fi->value, tvb, TRUE);
1894 }
1895
1896 /* Add a FT_PROTOCOL to a proto_tree */
1897 proto_item *
1898 proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
1899                                gint start, gint length, const char *format, ...)
1900 {
1901         proto_item        *pi;
1902         va_list            ap;
1903         header_field_info *hfinfo;
1904
1905         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
1906
1907         DISSECTOR_ASSERT(hfinfo->type == FT_PROTOCOL);
1908
1909         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
1910
1911         proto_tree_set_protocol_tvb(PNODE_FINFO(pi), (start == 0 ? tvb : tvb_new_subset(tvb, start, length, length)));
1912
1913         TRY_TO_FAKE_THIS_REPR(pi);
1914
1915         va_start(ap, format);
1916         proto_tree_set_representation(pi, format, ap);
1917         va_end(ap);
1918
1919         return pi;
1920 }
1921
1922
1923 /* Add a FT_BYTES to a proto_tree */
1924 proto_item *
1925 proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
1926                      gint length, const guint8 *start_ptr)
1927 {
1928         proto_item        *pi;
1929         header_field_info *hfinfo;
1930
1931         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
1932
1933         DISSECTOR_ASSERT(hfinfo->type == FT_BYTES);
1934
1935         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
1936         proto_tree_set_bytes(PNODE_FINFO(pi), start_ptr, length);
1937
1938         return pi;
1939 }
1940
1941 proto_item *
1942 proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
1943                                   gint start, gint length,
1944                                   const guint8 *start_ptr,
1945                                   const char *format, ...)
1946 {
1947         proto_item        *pi;
1948         va_list            ap;
1949         header_field_info *hfinfo;
1950
1951         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
1952
1953         if (start_ptr)
1954                 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length,
1955                                           start_ptr);
1956         else
1957                 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length,
1958                                           tvb_get_ptr(tvb, start, length));
1959
1960         va_start(ap, format);
1961         proto_tree_set_representation_value(pi, format, ap);
1962         va_end(ap);
1963
1964         return pi;
1965 }
1966
1967 proto_item *
1968 proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
1969                             gint start, gint length, const guint8 *start_ptr,
1970                             const char *format, ...)
1971 {
1972         proto_item        *pi;
1973         va_list            ap;
1974         header_field_info *hfinfo;
1975
1976         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
1977
1978         if (start_ptr)
1979                 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length,
1980                                           start_ptr);
1981         else
1982                 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length,
1983                                           tvb_get_ptr(tvb, start, length));
1984
1985         TRY_TO_FAKE_THIS_REPR(pi);
1986
1987         va_start(ap, format);
1988         proto_tree_set_representation(pi, format, ap);
1989         va_end(ap);
1990
1991         return pi;
1992 }
1993
1994 static void
1995 proto_tree_set_bytes(field_info *fi, const guint8* start_ptr, gint length)
1996 {
1997         GByteArray *bytes;
1998
1999         bytes = g_byte_array_new();
2000         if (length > 0) {
2001                 g_byte_array_append(bytes, start_ptr, length);
2002         }
2003         fvalue_set(&fi->value, bytes, TRUE);
2004 }
2005
2006
2007 static void
2008 proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, gint offset, gint length)
2009 {
2010         proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
2011 }
2012
2013 /* Add a FT_*TIME to a proto_tree */
2014 proto_item *
2015 proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2016                     gint length, nstime_t *value_ptr)
2017 {
2018         proto_item        *pi;
2019         header_field_info *hfinfo;
2020
2021         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2022
2023         DISSECTOR_ASSERT(hfinfo->type == FT_ABSOLUTE_TIME ||
2024                          hfinfo->type == FT_RELATIVE_TIME);
2025
2026         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2027         proto_tree_set_time(PNODE_FINFO(pi), value_ptr);
2028
2029         return pi;
2030 }
2031
2032 proto_item *
2033 proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2034                                  gint start, gint length, nstime_t *value_ptr,
2035                                  const char *format, ...)
2036 {
2037         proto_item        *pi;
2038         va_list            ap;
2039
2040         pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
2041         if (pi != tree) {
2042                 va_start(ap, format);
2043                 proto_tree_set_representation_value(pi, format, ap);
2044                 va_end(ap);
2045         }
2046
2047         return pi;
2048 }
2049
2050 proto_item *
2051 proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2052                            gint start, gint length, nstime_t *value_ptr,
2053                            const char *format, ...)
2054 {
2055         proto_item        *pi;
2056         va_list            ap;
2057
2058         pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
2059         if (pi != tree) {
2060                 TRY_TO_FAKE_THIS_REPR(pi);
2061
2062                 va_start(ap, format);
2063                 proto_tree_set_representation(pi, format, ap);
2064                 va_end(ap);
2065         }
2066
2067         return pi;
2068 }
2069
2070 /* Set the FT_*TIME value */
2071 static void
2072 proto_tree_set_time(field_info *fi, nstime_t *value_ptr)
2073 {
2074         DISSECTOR_ASSERT(value_ptr != NULL);
2075
2076         fvalue_set(&fi->value, value_ptr, FALSE);
2077 }
2078
2079 /* Add a FT_IPXNET to a proto_tree */
2080 proto_item *
2081 proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2082                       gint length, guint32 value)
2083 {
2084         proto_item        *pi;
2085         header_field_info *hfinfo;
2086
2087         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2088
2089         DISSECTOR_ASSERT(hfinfo->type == FT_IPXNET);
2090
2091         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2092         proto_tree_set_ipxnet(PNODE_FINFO(pi), value);
2093
2094         return pi;
2095 }
2096
2097 proto_item *
2098 proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2099                                    gint start, gint length, guint32 value,
2100                                    const char *format, ...)
2101 {
2102         proto_item        *pi;
2103         va_list            ap;
2104
2105         pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
2106         if (pi != tree) {
2107                 va_start(ap, format);
2108                 proto_tree_set_representation_value(pi, format, ap);
2109                 va_end(ap);
2110         }
2111
2112         return pi;
2113 }
2114
2115 proto_item *
2116 proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2117                              gint start, gint length, guint32 value,
2118                              const char *format, ...)
2119 {
2120         proto_item        *pi;
2121         va_list            ap;
2122
2123         pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
2124         if (pi != tree) {
2125                 TRY_TO_FAKE_THIS_REPR(pi);
2126
2127                 va_start(ap, format);
2128                 proto_tree_set_representation(pi, format, ap);
2129                 va_end(ap);
2130         }
2131
2132         return pi;
2133 }
2134
2135 /* Set the FT_IPXNET value */
2136 static void
2137 proto_tree_set_ipxnet(field_info *fi, guint32 value)
2138 {
2139         fvalue_set_uinteger(&fi->value, value);
2140 }
2141
2142 /* Add a FT_IPv4 to a proto_tree */
2143 proto_item *
2144 proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2145                     gint length, guint32 value)
2146 {
2147         proto_item        *pi;
2148         header_field_info *hfinfo;
2149
2150         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2151
2152         DISSECTOR_ASSERT(hfinfo->type == FT_IPv4);
2153
2154         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2155         proto_tree_set_ipv4(PNODE_FINFO(pi), value);
2156
2157         return pi;
2158 }
2159
2160 proto_item *
2161 proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2162                                  gint start, gint length, guint32 value,
2163                                  const char *format, ...)
2164 {
2165         proto_item        *pi;
2166         va_list            ap;
2167
2168         pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
2169         if (pi != tree) {
2170                 va_start(ap, format);
2171                 proto_tree_set_representation_value(pi, format, ap);
2172                 va_end(ap);
2173         }
2174
2175         return pi;
2176 }
2177
2178 proto_item *
2179 proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2180                            gint start, gint length, guint32 value,
2181                            const char *format, ...)
2182 {
2183         proto_item        *pi;
2184         va_list            ap;
2185
2186         pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
2187         if (pi != tree) {
2188                 TRY_TO_FAKE_THIS_REPR(pi);
2189
2190                 va_start(ap, format);
2191                 proto_tree_set_representation(pi, format, ap);
2192                 va_end(ap);
2193         }
2194
2195         return pi;
2196 }
2197
2198 /* Set the FT_IPv4 value */
2199 static void
2200 proto_tree_set_ipv4(field_info *fi, guint32 value)
2201 {
2202         fvalue_set_uinteger(&fi->value, value);
2203 }
2204
2205 /* Add a FT_IPv6 to a proto_tree */
2206 proto_item *
2207 proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2208                     gint length, const guint8* value_ptr)
2209 {
2210         proto_item        *pi;
2211         header_field_info *hfinfo;
2212
2213         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2214
2215         DISSECTOR_ASSERT(hfinfo->type == FT_IPv6);
2216
2217         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2218         proto_tree_set_ipv6(PNODE_FINFO(pi), value_ptr);
2219
2220         return pi;
2221 }
2222
2223 proto_item *
2224 proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2225                                  gint start, gint length,
2226                                  const guint8* value_ptr,
2227                                  const char *format, ...)
2228 {
2229         proto_item        *pi;
2230         va_list            ap;
2231
2232         pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
2233         if (pi != tree) {
2234                 va_start(ap, format);
2235                 proto_tree_set_representation_value(pi, format, ap);
2236                 va_end(ap);
2237         }
2238
2239         return pi;
2240 }
2241
2242 proto_item *
2243 proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2244                            gint start, gint length, const guint8* value_ptr,
2245                            const char *format, ...)
2246 {
2247         proto_item        *pi;
2248         va_list            ap;
2249
2250         pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
2251         if (pi != tree) {
2252                 TRY_TO_FAKE_THIS_REPR(pi);
2253
2254                 va_start(ap, format);
2255                 proto_tree_set_representation(pi, format, ap);
2256                 va_end(ap);
2257         }
2258
2259         return pi;
2260 }
2261
2262 /* Set the FT_IPv6 value */
2263 static void
2264 proto_tree_set_ipv6(field_info *fi, const guint8* value_ptr)
2265 {
2266         DISSECTOR_ASSERT(value_ptr != NULL);
2267         fvalue_set(&fi->value, (gpointer) value_ptr, FALSE);
2268 }
2269
2270 static void
2271 proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
2272 {
2273         proto_tree_set_ipv6(fi, tvb_get_ptr(tvb, start, length));
2274 }
2275
2276 /* Add a FT_GUID to a proto_tree */
2277 proto_item *
2278 proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2279                     gint length, const e_guid_t *value_ptr)
2280 {
2281         proto_item        *pi;
2282         header_field_info *hfinfo;
2283
2284         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2285
2286         DISSECTOR_ASSERT(hfinfo->type == FT_GUID);
2287
2288         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2289         proto_tree_set_guid(PNODE_FINFO(pi), value_ptr);
2290
2291         return pi;
2292 }
2293
2294 proto_item *
2295 proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2296                                  gint start, gint length,
2297                                  const e_guid_t *value_ptr,
2298                                  const char *format, ...)
2299 {
2300         proto_item        *pi;
2301         va_list            ap;
2302
2303         pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
2304         if (pi != tree) {
2305                 va_start(ap, format);
2306                 proto_tree_set_representation_value(pi, format, ap);
2307                 va_end(ap);
2308         }
2309
2310         return pi;
2311 }
2312
2313 proto_item *
2314 proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2315                            gint start, gint length, const e_guid_t *value_ptr,
2316                            const char *format, ...)
2317 {
2318         proto_item        *pi;
2319         va_list            ap;
2320
2321         pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
2322         if (pi != tree) {
2323                 TRY_TO_FAKE_THIS_REPR(pi);
2324
2325                 va_start(ap, format);
2326                 proto_tree_set_representation(pi, format, ap);
2327                 va_end(ap);
2328         }
2329
2330         return pi;
2331 }
2332
2333 /* Set the FT_GUID value */
2334 static void
2335 proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
2336 {
2337         DISSECTOR_ASSERT(value_ptr != NULL);
2338         fvalue_set(&fi->value, (gpointer) value_ptr, FALSE);
2339 }
2340
2341 static void
2342 proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, gint start,
2343                         const guint encoding)
2344 {
2345         e_guid_t guid;
2346
2347         tvb_get_guid(tvb, start, &guid, encoding);
2348         proto_tree_set_guid(fi, &guid);
2349 }
2350
2351 /* Add a FT_OID to a proto_tree */
2352 proto_item *
2353 proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2354                    gint length, const guint8* value_ptr)
2355 {
2356         proto_item        *pi;
2357         header_field_info *hfinfo;
2358
2359         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2360
2361         DISSECTOR_ASSERT(hfinfo->type == FT_OID);
2362
2363         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2364         proto_tree_set_oid(PNODE_FINFO(pi), value_ptr, length);
2365
2366         return pi;
2367 }
2368
2369 proto_item *
2370 proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2371                                 gint start, gint length,
2372                                 const guint8* value_ptr,
2373                                 const char *format, ...)
2374 {
2375         proto_item        *pi;
2376         va_list            ap;
2377
2378         pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
2379         if (pi != tree) {
2380                 va_start(ap, format);
2381                 proto_tree_set_representation_value(pi, format, ap);
2382                 va_end(ap);
2383         }
2384
2385         return pi;
2386 }
2387
2388 proto_item *
2389 proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2390                           gint start, gint length, const guint8* value_ptr,
2391                           const char *format, ...)
2392 {
2393         proto_item        *pi;
2394         va_list            ap;
2395
2396         pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
2397         if (pi != tree) {
2398                 TRY_TO_FAKE_THIS_REPR(pi);
2399
2400                 va_start(ap, format);
2401                 proto_tree_set_representation(pi, format, ap);
2402                 va_end(ap);
2403         }
2404
2405         return pi;
2406 }
2407
2408 /* Set the FT_OID value */
2409 static void
2410 proto_tree_set_oid(field_info *fi, const guint8* value_ptr, gint length)
2411 {
2412         GByteArray *bytes;
2413
2414         DISSECTOR_ASSERT(value_ptr != NULL);
2415
2416         bytes = g_byte_array_new();
2417         if (length > 0) {
2418                 g_byte_array_append(bytes, value_ptr, length);
2419         }
2420         fvalue_set(&fi->value, bytes, TRUE);
2421 }
2422
2423 static void
2424 proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
2425 {
2426         proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
2427 }
2428
2429 static void
2430 proto_tree_set_uint64(field_info *fi, guint64 value)
2431 {
2432         fvalue_set_integer64(&fi->value, value);
2433 }
2434
2435 /*
2436  * NOTE: to support code written when proto_tree_add_item() took a
2437  * gboolean as its last argument, with FALSE meaning "big-endian"
2438  * and TRUE meaning "little-endian", we treat any non-zero value of
2439  * "encoding" as meaning "little-endian".
2440  */
2441 static void
2442 proto_tree_set_uint64_tvb(field_info *fi, tvbuff_t *tvb, gint start,
2443                           guint length, const guint encoding)
2444 {
2445         guint64 value = 0;
2446         guint8* b = (guint8 *)ep_tvb_memdup(tvb, start, length);
2447
2448         if (encoding) {
2449                 b += length;
2450                 switch (length) {
2451                         default: DISSECTOR_ASSERT_NOT_REACHED();
2452                         case 8: value <<= 8; value += *--b;
2453                         case 7: value <<= 8; value += *--b;
2454                         case 6: value <<= 8; value += *--b;
2455                         case 5: value <<= 8; value += *--b;
2456                         case 4: value <<= 8; value += *--b;
2457                         case 3: value <<= 8; value += *--b;
2458                         case 2: value <<= 8; value += *--b;
2459                         case 1: value <<= 8; value += *--b;
2460                                 break;
2461                 }
2462         } else {
2463                 switch (length) {
2464                         default: DISSECTOR_ASSERT_NOT_REACHED();
2465                         case 8: value <<= 8; value += *b++;
2466                         case 7: value <<= 8; value += *b++;
2467                         case 6: value <<= 8; value += *b++;
2468                         case 5: value <<= 8; value += *b++;
2469                         case 4: value <<= 8; value += *b++;
2470                         case 3: value <<= 8; value += *b++;
2471                         case 2: value <<= 8; value += *b++;
2472                         case 1: value <<= 8; value += *b++;
2473                                 break;
2474                 }
2475         }
2476
2477         proto_tree_set_uint64(fi, value);
2478 }
2479
2480 /* Add a FT_STRING or FT_STRINGZ to a proto_tree. Creates own copy of string,
2481  * and frees it when the proto_tree is destroyed. */
2482 proto_item *
2483 proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2484                       gint length, const char* value)
2485 {
2486         proto_item        *pi;
2487         header_field_info *hfinfo;
2488
2489         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2490
2491         DISSECTOR_ASSERT(hfinfo->type == FT_STRING || hfinfo->type == FT_STRINGZ);
2492
2493         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2494         DISSECTOR_ASSERT(length >= 0);
2495         proto_tree_set_string(PNODE_FINFO(pi), value);
2496
2497         return pi;
2498 }
2499
2500 proto_item *
2501 proto_tree_add_unicode_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2502                       gint length, const char* value)
2503 {
2504         DISSECTOR_ASSERT(g_utf8_validate(value, -1, NULL));
2505         return proto_tree_add_string_format_value(tree, hfindex, tvb, start, length, value, "%s", value);
2506 }
2507
2508 proto_item *
2509 proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2510                                    gint start, gint length, const char* value,
2511                                    const char *format,
2512                                    ...)
2513 {
2514         proto_item        *pi;
2515         va_list            ap;
2516
2517         pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
2518         if (pi != tree) {
2519                 va_start(ap, format);
2520                 proto_tree_set_representation_value(pi, format, ap);
2521                 va_end(ap);
2522         }
2523
2524         return pi;
2525 }
2526
2527 proto_item *
2528 proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2529                              gint start, gint length, const char* value,
2530                              const char *format, ...)
2531 {
2532         proto_item        *pi;
2533         va_list            ap;
2534
2535         pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
2536         if (pi != tree) {
2537                 TRY_TO_FAKE_THIS_REPR(pi);
2538
2539                 va_start(ap, format);
2540                 proto_tree_set_representation(pi, format, ap);
2541                 va_end(ap);
2542         }
2543
2544         return pi;
2545 }
2546
2547 /* Appends string data to a FT_STRING or FT_STRINGZ, allowing progressive
2548  * field info update instead of only updating the representation as does
2549  * proto_item_append_text()
2550  */
2551 /* NOTE: this function will break with the TRY_TO_FAKE_THIS_ITEM()
2552  * speed optimization.
2553  * Currently only WSP use this function so it is not that bad but try to
2554  * avoid using this one if possible.
2555  * IF you must use this function you MUST also disable the
2556  * TRY_TO_FAKE_THIS_ITEM() optimization for your dissector/function
2557  * using proto_item_append_string().
2558  * Do that by faking that the tree is visible by calling
2559  * proto_tree_set_visible(tree, TRUE) (see packet-wsp.c)
2560  * BEFORE you create the item you are later going to use
2561  * proto_item_append_string() on.
2562  */
2563 void
2564 proto_item_append_string(proto_item *pi, const char *str)
2565 {
2566         field_info        *fi;
2567         header_field_info *hfinfo;
2568         const gchar       *old_str, *new_str;
2569
2570         if (!pi)
2571                 return;
2572         if (!*str)
2573                 return;
2574
2575         fi = PITEM_FINFO(pi);
2576         DISSECTOR_ASSERT_HINT(fi, "proto_tree_set_visible(tree, TRUE) should have been called previously");
2577
2578         hfinfo = fi->hfinfo;
2579         if (hfinfo->type == FT_PROTOCOL) {
2580                 /* TRY_TO_FAKE_THIS_ITEM() speed optimization: silently skip */
2581                 return;
2582         }
2583         DISSECTOR_ASSERT(hfinfo->type == FT_STRING || hfinfo->type == FT_STRINGZ);
2584         old_str = (guint8 *)fvalue_get(&fi->value);
2585         if (old_str && old_str[0])
2586                 new_str = ep_strconcat(old_str, str, NULL);
2587         else
2588                 new_str = str;
2589         fvalue_set(&fi->value, (gpointer) new_str, FALSE);
2590 }
2591
2592 /* Set the FT_STRING value */
2593 static void
2594 proto_tree_set_string(field_info *fi, const char* value)
2595 {
2596         if (value) {
2597                 fvalue_set(&fi->value, (gpointer) value, FALSE);
2598         } else {
2599                 fvalue_set(&fi->value, (gpointer) "[ Null ]", FALSE);
2600         }
2601 }
2602
2603 static void
2604 proto_tree_set_string_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length, gint encoding)
2605 {
2606         gchar   *string;
2607
2608         if (length == -1) {
2609                 length = tvb_ensure_length_remaining(tvb, start);
2610         }
2611
2612         string = tvb_get_ephemeral_string_enc(tvb, start, length, encoding);
2613         proto_tree_set_string(fi, string);
2614 }
2615
2616
2617 /* Add a FT_AX25 to a proto_tree */
2618 proto_item *
2619 proto_tree_add_ax25(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
2620                 const guint8* value)
2621 {
2622         proto_item              *pi;
2623         header_field_info       *hfinfo;
2624
2625         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2626
2627         DISSECTOR_ASSERT(hfinfo->type == FT_AX25);
2628
2629         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2630         proto_tree_set_ax25(PNODE_FINFO(pi), value);
2631
2632         return pi;
2633 }
2634
2635 /* Set the FT_AX25 value */
2636 static void
2637 proto_tree_set_ax25(field_info *fi, const guint8* value)
2638 {
2639         fvalue_set(&fi->value, (gpointer) value, FALSE);
2640 }
2641
2642 static void
2643 proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, gint start)
2644 {
2645         proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
2646 }
2647
2648 /* Set the FT_VINES value */
2649 static void
2650 proto_tree_set_vines(field_info *fi, const guint8* value)
2651 {
2652         fvalue_set(&fi->value, (gpointer) value, FALSE);
2653 }
2654
2655 static void
2656 proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, gint start)
2657 {
2658         proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN));
2659 }
2660
2661 /* Add a FT_ETHER to a proto_tree */
2662 proto_item *
2663 proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2664                      gint length, const guint8* value)
2665 {
2666         proto_item        *pi;
2667         header_field_info *hfinfo;
2668
2669         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2670
2671         DISSECTOR_ASSERT(hfinfo->type == FT_ETHER);
2672
2673         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2674         proto_tree_set_ether(PNODE_FINFO(pi), value);
2675
2676         return pi;
2677 }
2678
2679 proto_item *
2680 proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2681                                   gint start, gint length, const guint8* value,
2682                                   const char *format, ...)
2683 {
2684         proto_item        *pi;
2685         va_list            ap;
2686
2687         pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
2688         if (pi != tree) {
2689                 va_start(ap, format);
2690                 proto_tree_set_representation_value(pi, format, ap);
2691                 va_end(ap);
2692         }
2693
2694         return pi;
2695 }
2696
2697 proto_item *
2698 proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2699                             gint start, gint length, const guint8* value,
2700                             const char *format, ...)
2701 {
2702         proto_item        *pi;
2703         va_list            ap;
2704
2705         pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
2706         if (pi != tree) {
2707                 TRY_TO_FAKE_THIS_REPR(pi);
2708
2709                 va_start(ap, format);
2710                 proto_tree_set_representation(pi, format, ap);
2711                 va_end(ap);
2712         }
2713
2714         return pi;
2715 }
2716
2717 /* Set the FT_ETHER value */
2718 static void
2719 proto_tree_set_ether(field_info *fi, const guint8* value)
2720 {
2721         fvalue_set(&fi->value, (gpointer) value, FALSE);
2722 }
2723
2724 static void
2725 proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, gint start)
2726 {
2727         proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN));
2728 }
2729
2730 /* Add a FT_BOOLEAN to a proto_tree */
2731 proto_item *
2732 proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2733                        gint length, guint32 value)
2734 {
2735         proto_item        *pi;
2736         header_field_info *hfinfo;
2737
2738         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2739
2740         DISSECTOR_ASSERT(hfinfo->type == FT_BOOLEAN);
2741
2742         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2743         proto_tree_set_boolean(PNODE_FINFO(pi), value);
2744
2745         return pi;
2746 }
2747
2748 proto_item *
2749 proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
2750                                     tvbuff_t *tvb, gint start, gint length,
2751                                     guint32 value, const char *format, ...)
2752 {
2753         proto_item        *pi;
2754         va_list            ap;
2755
2756         pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
2757         if (pi != tree) {
2758                 va_start(ap, format);
2759                 proto_tree_set_representation_value(pi, format, ap);
2760                 va_end(ap);
2761         }
2762
2763         return pi;
2764 }
2765
2766 proto_item *
2767 proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2768                               gint start, gint length, guint32 value,
2769                               const char *format, ...)
2770 {
2771         proto_item        *pi;
2772         va_list            ap;
2773
2774         pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
2775         if (pi != tree) {
2776                 TRY_TO_FAKE_THIS_REPR(pi);
2777
2778                 va_start(ap, format);
2779                 proto_tree_set_representation(pi, format, ap);
2780                 va_end(ap);
2781         }
2782
2783         return pi;
2784 }
2785
2786 /* Set the FT_BOOLEAN value */
2787 static void
2788 proto_tree_set_boolean(field_info *fi, guint32 value)
2789 {
2790         proto_tree_set_uint(fi, value);
2791 }
2792
2793 /* Add a FT_FLOAT to a proto_tree */
2794 proto_item *
2795 proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2796                      gint length, float value)
2797 {
2798         proto_item        *pi;
2799         header_field_info *hfinfo;
2800
2801         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2802
2803         DISSECTOR_ASSERT(hfinfo->type == FT_FLOAT);
2804
2805         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2806         proto_tree_set_float(PNODE_FINFO(pi), value);
2807
2808         return pi;
2809 }
2810
2811 proto_item *
2812 proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2813                                   gint start, gint length, float value,
2814                                   const char *format, ...)
2815 {
2816         proto_item        *pi;
2817         va_list            ap;
2818
2819         pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
2820         if (pi != tree) {
2821                 va_start(ap, format);
2822                 proto_tree_set_representation_value(pi, format, ap);
2823                 va_end(ap);
2824         }
2825
2826         return pi;
2827 }
2828
2829 proto_item *
2830 proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2831                             gint start, gint length, float value,
2832                             const char *format, ...)
2833 {
2834         proto_item        *pi;
2835         va_list            ap;
2836
2837         pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
2838         if (pi != tree) {
2839                 TRY_TO_FAKE_THIS_REPR(pi);
2840
2841                 va_start(ap, format);
2842                 proto_tree_set_representation(pi, format, ap);
2843                 va_end(ap);
2844         }
2845
2846         return pi;
2847 }
2848
2849 /* Set the FT_FLOAT value */
2850 static void
2851 proto_tree_set_float(field_info *fi, float value)
2852 {
2853         fvalue_set_floating(&fi->value, value);
2854 }
2855
2856 /* Add a FT_DOUBLE to a proto_tree */
2857 proto_item *
2858 proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2859                       gint length, double value)
2860 {
2861         proto_item        *pi;
2862         header_field_info *hfinfo;
2863
2864         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2865
2866         DISSECTOR_ASSERT(hfinfo->type == FT_DOUBLE);
2867
2868         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2869         proto_tree_set_double(PNODE_FINFO(pi), value);
2870
2871         return pi;
2872 }
2873
2874 proto_item *
2875 proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2876                                    gint start, gint length, double value,
2877                                    const char *format, ...)
2878 {
2879         proto_item        *pi;
2880         va_list            ap;
2881
2882         pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
2883         if (pi != tree) {
2884                 va_start(ap, format);
2885                 proto_tree_set_representation_value(pi, format, ap);
2886                 va_end(ap);
2887         }
2888
2889         return pi;
2890 }
2891
2892 proto_item *
2893 proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2894                              gint start, gint length, double value,
2895                              const char *format, ...)
2896 {
2897         proto_item        *pi;
2898         va_list            ap;
2899
2900         pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
2901         if (pi != tree) {
2902                 TRY_TO_FAKE_THIS_REPR(pi);
2903
2904                 va_start(ap, format);
2905                 proto_tree_set_representation(pi, format, ap);
2906                 va_end(ap);
2907         }
2908
2909         return pi;
2910 }
2911
2912 /* Set the FT_DOUBLE value */
2913 static void
2914 proto_tree_set_double(field_info *fi, double value)
2915 {
2916         fvalue_set_floating(&fi->value, value);
2917 }
2918
2919 /* Add FT_UINT{8,16,24,32} to a proto_tree */
2920 proto_item *
2921 proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2922                     gint length, guint32 value)
2923 {
2924         proto_item        *pi = NULL;
2925         header_field_info *hfinfo;
2926
2927         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
2928
2929         switch (hfinfo->type) {
2930                 case FT_UINT8:
2931                 case FT_UINT16:
2932                 case FT_UINT24:
2933                 case FT_UINT32:
2934                 case FT_FRAMENUM:
2935                         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
2936                         proto_tree_set_uint(PNODE_FINFO(pi), value);
2937                         break;
2938
2939                 default:
2940                         DISSECTOR_ASSERT_NOT_REACHED();
2941         }
2942
2943         return pi;
2944 }
2945
2946 proto_item *
2947 proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2948                                  gint start, gint length, guint32 value,
2949                                  const char *format, ...)
2950 {
2951         proto_item        *pi;
2952         va_list            ap;
2953
2954         pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
2955         if (pi != tree) {
2956                 va_start(ap, format);
2957                 proto_tree_set_representation_value(pi, format, ap);
2958                 va_end(ap);
2959         }
2960
2961         return pi;
2962 }
2963
2964 proto_item *
2965 proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
2966                            gint start, gint length, guint32 value,
2967                            const char *format, ...)
2968 {
2969         proto_item        *pi;
2970         va_list            ap;
2971
2972         pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
2973         if (pi != tree) {
2974                 TRY_TO_FAKE_THIS_REPR(pi);
2975
2976                 va_start(ap, format);
2977                 proto_tree_set_representation(pi, format, ap);
2978                 va_end(ap);
2979         }
2980
2981         return pi;
2982 }
2983
2984 /* Set the FT_UINT{8,16,24,32} value */
2985 static void
2986 proto_tree_set_uint(field_info *fi, guint32 value)
2987 {
2988         header_field_info *hfinfo;
2989         guint32            integer;
2990
2991         hfinfo = fi->hfinfo;
2992         integer = value;
2993
2994         if (hfinfo->bitmask) {
2995                 /* Mask out irrelevant portions */
2996                 integer &= hfinfo->bitmask;
2997
2998                 /* Shift bits */
2999                 integer >>= hfinfo_bitshift(hfinfo);
3000         }
3001
3002         fvalue_set_uinteger(&fi->value, integer);
3003 }
3004
3005 /* Add FT_UINT64 to a proto_tree */
3006 proto_item *
3007 proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3008                       gint length, guint64 value)
3009 {
3010         proto_item        *pi;
3011         header_field_info *hfinfo;
3012
3013         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3014
3015         DISSECTOR_ASSERT(hfinfo->type == FT_UINT64);
3016
3017         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3018         proto_tree_set_uint64(PNODE_FINFO(pi), value);
3019
3020         return pi;
3021 }
3022
3023 proto_item *
3024 proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3025                                    gint start, gint length, guint64 value,
3026                                    const char *format, ...)
3027 {
3028         proto_item        *pi;
3029         va_list            ap;
3030
3031         pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
3032         if (pi != tree) {
3033                 va_start(ap, format);
3034                 proto_tree_set_representation_value(pi, format, ap);
3035                 va_end(ap);
3036         }
3037
3038         return pi;
3039 }
3040
3041 proto_item *
3042 proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3043                              gint start, gint length, guint64 value,
3044                              const char *format, ...)
3045 {
3046         proto_item        *pi;
3047         va_list            ap;
3048
3049         pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
3050         if (pi != tree) {
3051                 TRY_TO_FAKE_THIS_REPR(pi);
3052
3053                 va_start(ap, format);
3054                 proto_tree_set_representation(pi, format, ap);
3055                 va_end(ap);
3056         }
3057
3058         return pi;
3059 }
3060
3061 /* Add FT_INT{8,16,24,32} to a proto_tree */
3062 proto_item *
3063 proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3064                    gint length, gint32 value)
3065 {
3066         proto_item        *pi = NULL;
3067         header_field_info *hfinfo;
3068
3069         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3070
3071         switch (hfinfo->type) {
3072                 case FT_INT8:
3073                 case FT_INT16:
3074                 case FT_INT24:
3075                 case FT_INT32:
3076                         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3077                         proto_tree_set_int(PNODE_FINFO(pi), value);
3078                         break;
3079
3080                 default:
3081                         DISSECTOR_ASSERT_NOT_REACHED();
3082         }
3083
3084         return pi;
3085 }
3086
3087 proto_item *
3088 proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3089                                 gint start, gint length, gint32 value,
3090                                 const char *format, ...)
3091 {
3092         proto_item  *pi;
3093         va_list      ap;
3094
3095         pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
3096         if (pi != tree) {
3097                 va_start(ap, format);
3098                 proto_tree_set_representation_value(pi, format, ap);
3099                 va_end(ap);
3100         }
3101
3102         return pi;
3103 }
3104
3105 proto_item *
3106 proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3107                           gint start, gint length, gint32 value,
3108                           const char *format, ...)
3109 {
3110         proto_item *pi;
3111         va_list     ap;
3112
3113         pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
3114         if (pi != tree) {
3115                 TRY_TO_FAKE_THIS_REPR(pi);
3116
3117                 va_start(ap, format);
3118                 proto_tree_set_representation(pi, format, ap);
3119                 va_end(ap);
3120         }
3121
3122         return pi;
3123 }
3124
3125 /* Set the FT_INT{8,16,24,32} value */
3126 static void
3127 proto_tree_set_int(field_info *fi, gint32 value)
3128 {
3129         header_field_info *hfinfo;
3130         guint32            integer;
3131
3132         hfinfo = fi->hfinfo;
3133         integer = (guint32) value;
3134
3135         if (hfinfo->bitmask) {
3136                 /* Mask out irrelevant portions */
3137                 integer &= hfinfo->bitmask;
3138
3139                 /* Shift bits */
3140                 integer >>= hfinfo_bitshift(hfinfo);
3141         }
3142
3143         fvalue_set_sinteger(&fi->value, integer);
3144 }
3145
3146 /* Add FT_INT64 to a proto_tree */
3147 proto_item *
3148 proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3149                      gint length, gint64 value)
3150 {
3151         proto_item        *pi;
3152         header_field_info *hfinfo;
3153
3154         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3155
3156         DISSECTOR_ASSERT(hfinfo->type == FT_INT64);
3157
3158         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3159         proto_tree_set_uint64(PNODE_FINFO(pi), (guint64)value);
3160
3161         return pi;
3162 }
3163
3164 proto_item *
3165 proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3166                                   gint start, gint length, gint64 value,
3167                                   const char *format, ...)
3168 {
3169         proto_item        *pi;
3170         va_list            ap;
3171
3172         pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
3173         if (pi != tree) {
3174                 va_start(ap, format);
3175                 proto_tree_set_representation_value(pi, format, ap);
3176                 va_end(ap);
3177         }
3178
3179         return pi;
3180 }
3181
3182 proto_item *
3183 proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3184                            gint start, gint length, gint64 value,
3185                            const char *format, ...)
3186 {
3187         proto_item        *pi;
3188         va_list            ap;
3189
3190         pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
3191         if (pi != tree) {
3192                 TRY_TO_FAKE_THIS_REPR(pi);
3193
3194                 va_start(ap, format);
3195                 proto_tree_set_representation(pi, format, ap);
3196                 va_end(ap);
3197         }
3198
3199         return pi;
3200 }
3201 /* Add a FT_EUI64 to a proto_tree */
3202 proto_item *
3203 proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
3204                      gint length, const guint64 value)
3205 {
3206         proto_item        *pi;
3207         header_field_info *hfinfo;
3208
3209         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
3210
3211         DISSECTOR_ASSERT(hfinfo->type == FT_EUI64);
3212
3213         pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
3214         proto_tree_set_eui64(PNODE_FINFO(pi), value);
3215
3216         return pi;
3217 }
3218
3219 proto_item *
3220 proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3221                                   gint start, gint length, const guint64 value,
3222                                   const char *format, ...)
3223 {
3224         proto_item        *pi;
3225         va_list            ap;
3226
3227         pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
3228         if (pi != tree) {
3229                 va_start(ap, format);
3230                 proto_tree_set_representation_value(pi, format, ap);
3231                 va_end(ap);
3232         }
3233
3234         return pi;
3235 }
3236
3237 proto_item *
3238 proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3239                             gint start, gint length, const guint64 value,
3240                             const char *format, ...)
3241 {
3242         proto_item        *pi;
3243         va_list            ap;
3244
3245         pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
3246         if (pi != tree) {
3247                 TRY_TO_FAKE_THIS_REPR(pi);
3248
3249                 va_start(ap, format);
3250                 proto_tree_set_representation(pi, format, ap);
3251                 va_end(ap);
3252         }
3253
3254         return pi;
3255 }
3256
3257 /* Set the FT_EUI64 value */
3258 static void
3259 proto_tree_set_eui64(field_info *fi, const guint64 value)
3260 {
3261         fvalue_set_integer64(&fi->value, value);
3262 }
3263 static void
3264 proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, gint start, const guint encoding)
3265 {
3266         if (encoding)
3267         {
3268                 proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
3269         } else {
3270                 proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
3271         }
3272 }
3273
3274 /* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
3275 static proto_item *
3276 proto_tree_add_node(proto_tree *tree, field_info *fi)
3277 {
3278         proto_node *pnode, *tnode, *sibling;
3279         field_info *tfi;
3280
3281         /*
3282          * Make sure "tree" is ready to have subtrees under it, by
3283          * checking whether it's been given an ett_ value.
3284          *
3285          * "PNODE_FINFO(tnode)" may be null; that's the case for the root
3286          * node of the protocol tree.  That node is not displayed,
3287          * so it doesn't need an ett_ value to remember whether it
3288          * was expanded.
3289          */
3290         tnode = tree;
3291         tfi = PNODE_FINFO(tnode);
3292         if (tfi != NULL && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
3293                 REPORT_DISSECTOR_BUG(ep_strdup_printf("\"%s\" - \"%s\" tfi->tree_type: %u invalid (%s:%u)",
3294                                      fi->hfinfo->name, fi->hfinfo->abbrev, tfi->tree_type, __FILE__, __LINE__));
3295                 /* XXX - is it safe to continue here? */
3296         }
3297
3298         PROTO_NODE_NEW(pnode);
3299         pnode->parent = tnode;
3300         PNODE_FINFO(pnode) = fi;
3301         pnode->tree_data = PTREE_DATA(tree);
3302
3303         if (tnode->last_child != NULL) {
3304                 sibling = tnode->last_child;
3305                 DISSECTOR_ASSERT(sibling->next == NULL);
3306                 sibling->next = pnode;
3307         } else
3308                 tnode->first_child = pnode;
3309         tnode->last_child = pnode;
3310
3311         tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
3312
3313         return (proto_item *)pnode;
3314 }
3315
3316
3317 /* Generic way to allocate field_info and add to proto_tree.
3318  * Sets *pfi to address of newly-allocated field_info struct */
3319 static proto_item *
3320 proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, gint start,
3321                   gint *length)
3322 {
3323         proto_item *pi;
3324         field_info *fi;
3325
3326         fi = alloc_field_info(tree, hfinfo, tvb, start, length);
3327         pi = proto_tree_add_node(tree, fi);
3328
3329         return pi;
3330 }
3331
3332
3333 static void
3334 get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const gint start, gint *length,
3335                    gint *item_length)
3336 {
3337         gint length_remaining;
3338
3339         /*
3340          * We only allow a null tvbuff if the item has a zero length,
3341          * i.e. if there's no data backing it.
3342          */
3343         DISSECTOR_ASSERT(tvb != NULL || *length == 0);
3344
3345         /*
3346          * XXX - in some protocols, there are 32-bit unsigned length
3347          * fields, so lengths in protocol tree and tvbuff routines
3348          * should really be unsigned.  We should have, for those
3349          * field types for which "to the end of the tvbuff" makes sense,
3350          * additional routines that take no length argument and
3351          * add fields that run to the end of the tvbuff.
3352          */
3353         if (*length == -1) {
3354                 /*
3355                  * For FT_NONE, FT_PROTOCOL, FT_BYTES, and FT_STRING fields,
3356                  * a length of -1 means "set the length to what remains in
3357                  * the tvbuff".
3358                  *
3359                  * The assumption is either that
3360                  *
3361                  *      1) the length of the item can only be determined
3362                  *         by dissection (typically true of items with
3363                  *         subitems, which are probably FT_NONE or
3364                  *         FT_PROTOCOL)
3365                  *
3366                  * or
3367                  *
3368                  *      2) if the tvbuff is "short" (either due to a short
3369                  *         snapshot length or due to lack of reassembly of
3370                  *         fragments/segments/whatever), we want to display
3371                  *         what's available in the field (probably FT_BYTES
3372                  *         or FT_STRING) and then throw an exception later
3373                  *
3374                  * or
3375                  *
3376                  *      3) the field is defined to be "what's left in the
3377                  *         packet"
3378                  *
3379                  * so we set the length to what remains in the tvbuff so
3380                  * that, if we throw an exception while dissecting, it
3381                  * has what is probably the right value.
3382                  *
3383                  * For FT_STRINGZ, it means "the string is null-terminated,
3384                  * not null-padded; set the length to the actual length
3385                  * of the string", and if the tvbuff if short, we just
3386                  * throw an exception.
3387                  *
3388                  * It's not valid for any other type of field.
3389                  */
3390                 switch (hfinfo->type) {
3391
3392                 case FT_PROTOCOL:
3393                         /*
3394                          * We allow this to be zero-length - for
3395                          * example, an ONC RPC NULL procedure has
3396                          * neither arguments nor reply, so the
3397                          * payload for that protocol is empty.
3398                          *
3399                          * However, if the length is negative, the
3400                          * start offset is *past* the byte past the
3401                          * end of the tvbuff, so we throw an
3402                          * exception.
3403                          */
3404                         *length = tvb_length_remaining(tvb, start);
3405                         if (*length < 0) {
3406                                 /*
3407                                  * Use "tvb_ensure_bytes_exist()"
3408                                  * to force the appropriate exception
3409                                  * to be thrown.
3410                                  */
3411                                 tvb_ensure_bytes_exist(tvb, start, 0);
3412                         }
3413                         DISSECTOR_ASSERT(*length >= 0);
3414                         break;
3415
3416                 case FT_NONE:
3417                 case FT_BYTES:
3418                 case FT_STRING:
3419                         *length = tvb_ensure_length_remaining(tvb, start);
3420                         DISSECTOR_ASSERT(*length >= 0);
3421                         break;
3422
3423                 case FT_STRINGZ:
3424                         /*
3425                          * Leave the length as -1, so our caller knows
3426                          * it was -1.
3427                          */
3428                         break;
3429
3430                 default:
3431                         DISSECTOR_ASSERT_NOT_REACHED();
3432                 }
3433                 *item_length = *length;
3434         } else {
3435                 *item_length = *length;
3436                 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
3437                         /*
3438                          * These types are for interior nodes of the
3439                          * tree, and don't have data associated with
3440                          * them; if the length is negative (XXX - see
3441                          * above) or goes past the end of the tvbuff,
3442                          * cut it short at the end of the tvbuff.
3443                          * That way, if this field is selected in
3444                          * Wireshark, we don't highlight stuff past
3445                          * the end of the data.
3446                          */
3447                         /* XXX - what to do, if we don't have a tvb? */
3448                         if (tvb) {
3449                                 length_remaining = tvb_length_remaining(tvb, start);
3450                                 if (*item_length < 0 ||
3451                                         (*item_length > 0 &&
3452                                           (length_remaining < *item_length)))
3453                                         *item_length = length_remaining;
3454                         }
3455                 }
3456                 if (*item_length < 0) {
3457                         THROW(ReportedBoundsError);
3458                 }
3459         }
3460 }
3461
3462 static field_info *
3463 new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
3464                const gint start, const gint item_length)
3465 {
3466         field_info *fi;
3467
3468         FIELD_INFO_NEW(fi);
3469
3470         fi->hfinfo     = hfinfo;
3471         fi->start      = start;
3472         fi->start     += (tvb)?tvb_raw_offset(tvb):0;
3473         fi->length     = item_length;
3474         fi->tree_type  = -1;
3475         fi->flags      = 0;
3476         if (!PTREE_DATA(tree)->visible)
3477                 FI_SET_FLAG(fi, FI_HIDDEN);
3478         fvalue_init(&fi->value, fi->hfinfo->type);
3479         fi->rep        = NULL;
3480
3481         /* add the data source tvbuff */
3482         fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL;
3483
3484         fi->appendix_start  = 0;
3485         fi->appendix_length = 0;
3486
3487         return fi;
3488 }
3489
3490 static field_info *
3491 alloc_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, const gint start,
3492                  gint *length)
3493 {
3494         gint               item_length;
3495
3496         get_hfi_length(hfinfo, tvb, start, length, &item_length);
3497         return new_field_info(tree, hfinfo, tvb, start, item_length);
3498 }
3499
3500 static void
3501 label_mark_truncated_start(char *label_str)
3502 {
3503         static const char trunc_str[] = "[truncated] ";
3504         const size_t trunc_len = sizeof(trunc_str)-1;
3505
3506         memmove(label_str + trunc_len, label_str, ITEM_LABEL_LENGTH - trunc_len);
3507         memcpy(label_str, trunc_str, trunc_len);
3508         label_str[ITEM_LABEL_LENGTH-1] = '\0';
3509 }
3510
3511 /* If the protocol tree is to be visible, set the representation of a
3512    proto_tree entry with the name of the field for the item and with
3513    the value formatted with the supplied printf-style format and
3514    argument list. */
3515 static void
3516 proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
3517 {
3518         g_assert(pi);
3519
3520         /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
3521          * items string representation */
3522         if (PTREE_DATA(pi)->visible && !PROTO_ITEM_IS_HIDDEN(pi)) {
3523                 int               ret = 0;
3524                 field_info        *fi = PITEM_FINFO(pi);
3525                 header_field_info *hf;
3526
3527                 DISSECTOR_ASSERT(fi);
3528
3529                 hf = fi->hfinfo;
3530
3531                 ITEM_LABEL_NEW(fi->rep);
3532                 if (hf->bitmask && (hf->type == FT_BOOLEAN || IS_FT_UINT(hf->type))) {
3533                         guint32 val;
3534                         char *p;
3535
3536                         val = fvalue_get_uinteger(&fi->value);
3537                         val <<= hfinfo_bitshift(hf);
3538
3539                         p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_bitwidth(hf));
3540                         ret = (int) (p - fi->rep->representation);
3541                 }
3542
3543                 /* put in the hf name */
3544                 ret += g_snprintf(fi->rep->representation + ret, ITEM_LABEL_LENGTH - ret, "%s: ", hf->name);
3545
3546                 /* If possible, Put in the value of the string */
3547                 if (ret < ITEM_LABEL_LENGTH) {
3548                         ret += g_vsnprintf(fi->rep->representation + ret,
3549                                           ITEM_LABEL_LENGTH - ret, format, ap);
3550                 }
3551                 if (ret >= ITEM_LABEL_LENGTH) {
3552                         /* Uh oh, we don't have enough room.  Tell the user
3553                          * that the field is truncated.
3554                          */
3555                         /* XXX, label_mark_truncated() ? */
3556                         label_mark_truncated_start(fi->rep->representation);
3557                 }
3558         }
3559 }
3560
3561 /* If the protocol tree is to be visible, set the representation of a
3562    proto_tree entry with the representation formatted with the supplied
3563    printf-style format and argument list. */
3564 static void
3565 proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
3566 {
3567         int         ret;        /*tmp return value */
3568         field_info *fi = PITEM_FINFO(pi);
3569
3570         DISSECTOR_ASSERT(fi);
3571
3572         if (!PROTO_ITEM_IS_HIDDEN(pi)) {
3573                 ITEM_LABEL_NEW(fi->rep);
3574                 ret = g_vsnprintf(fi->rep->representation, ITEM_LABEL_LENGTH,
3575                                   format, ap);
3576                 if (ret >= ITEM_LABEL_LENGTH) {
3577                         /* Uh oh, we don't have enough room.  Tell the user
3578                          * that the field is truncated.
3579                          */
3580                         label_mark_truncated_start(fi->rep->representation);
3581                 }
3582         }
3583 }
3584
3585 static int
3586 protoo_strlcpy(gchar *dest, const gchar *src, gsize dest_size)
3587 {
3588         gsize res = g_strlcpy(dest, src, dest_size);
3589
3590         if (res > dest_size)
3591                 res = dest_size;
3592         return (int) res;
3593 }
3594
3595 static header_field_info *
3596 hfinfo_same_name_get_prev(const header_field_info *hfinfo)
3597 {
3598         if (hfinfo->same_name_prev_id == -1)
3599                 return NULL;
3600         return proto_registrar_get_nth(hfinfo->same_name_prev_id);
3601 }
3602
3603 /* -------------------------- */
3604 const gchar *
3605 proto_custom_set(proto_tree* tree, const int field_id, gint occurrence,
3606                  gchar *result, gchar *expr, const int size)
3607 {
3608         guint32            number;
3609         guint8            *bytes;
3610         ipv4_addr         *ipv4;
3611         struct e_in6_addr *ipv6;
3612         address            addr;
3613         guint32            n_addr; /* network-order IPv4 address */
3614
3615         const true_false_string  *tfstring;
3616
3617         int                 len, prev_len = 0, last, i, offset_r = 0, offset_e = 0;
3618         GPtrArray          *finfos;
3619         field_info         *finfo         = NULL;
3620         header_field_info*  hfinfo;
3621         const gchar        *abbrev        = NULL;
3622
3623         const char *hf_str_val;
3624         char number_buf[32];
3625         const char *number_out;
3626
3627         g_assert(field_id >= 0);
3628
3629         hfinfo = proto_registrar_get_nth((guint)field_id);
3630
3631         /* do we need to rewind ? */
3632         if (!hfinfo)
3633                 return "";
3634
3635         if (occurrence < 0) {
3636                 /* Search other direction */
3637                 while (hfinfo->same_name_prev_id != -1) {
3638                         hfinfo = proto_registrar_get_nth(hfinfo->same_name_prev_id);
3639                 }
3640         }
3641
3642         while (hfinfo) {
3643                 finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
3644
3645                 if (!finfos || !(len = g_ptr_array_len(finfos))) {
3646                         if (occurrence < 0) {
3647                                 hfinfo = hfinfo->same_name_next;
3648                         } else {
3649                                 hfinfo = hfinfo_same_name_get_prev(hfinfo);
3650                         }
3651                         continue;
3652                 }
3653
3654                 /* Are there enough occurrences of the field? */
3655                 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
3656                         if (occurrence < 0) {
3657                                 hfinfo = hfinfo->same_name_next;
3658                         } else {
3659                                 hfinfo = hfinfo_same_name_get_prev(hfinfo);
3660                         }
3661                         prev_len += len;
3662                         continue;
3663                 }
3664
3665                 /* Calculate single index or set outer bounderies */
3666                 if (occurrence < 0) {
3667                         i = occurrence + len + prev_len;
3668                         last = i;
3669                 } else if (occurrence > 0) {
3670                         i = occurrence - 1 - prev_len;
3671                         last = i;
3672                 } else {
3673                         i = 0;
3674                         last = len - 1;
3675                 }
3676
3677                 prev_len += len; /* Count handled occurrences */
3678
3679                 while (i <= last) {
3680                         finfo = (field_info *)g_ptr_array_index(finfos, i);
3681
3682                         if (offset_r && (offset_r < (size - 2)))
3683                                 result[offset_r++] = ',';
3684
3685                         if (offset_e && (offset_e < (size - 2)))
3686                                 expr[offset_e++] = ',';
3687
3688                         switch (hfinfo->type) {
3689
3690                         case FT_NONE: /* Nothing to add */
3691                                 if (offset_r == 0) {
3692                                         result[0] = '\0';
3693                                 } else if (result[offset_r-1] == ',') {
3694                                         result[offset_r-1] = '\0';
3695                                 }
3696                                 break;
3697
3698                         case FT_PROTOCOL:
3699                                 /* prevent multiple "yes" entries by setting result directly */
3700                                 g_strlcpy(result, "Yes", size);
3701                                 break;
3702
3703                         case FT_UINT_BYTES:
3704                         case FT_BYTES:
3705                                 bytes = (guint8 *)fvalue_get(&finfo->value);
3706                                 offset_r += protoo_strlcpy(result+offset_r,
3707                                                            bytes_to_str(bytes,
3708                                                                         fvalue_length(&finfo->value)),
3709                                                            size-offset_r);
3710                                 break;
3711
3712                         case FT_ABSOLUTE_TIME:
3713                                 offset_r += protoo_strlcpy(result+offset_r,
3714                                                            abs_time_to_str((const nstime_t *)fvalue_get(&finfo->value),
3715                                                                            (absolute_time_display_e)hfinfo->display, TRUE),
3716                                                            size-offset_r);
3717                                 break;
3718
3719                         case FT_RELATIVE_TIME:
3720                                 offset_r += protoo_strlcpy(result+offset_r,
3721                                                            rel_time_to_secs_str((const nstime_t *)fvalue_get(&finfo->value)),
3722                                                            size-offset_r);
3723                                 break;
3724
3725                         case FT_BOOLEAN:
3726                                 number = fvalue_get_uinteger(&finfo->value);
3727                                 tfstring = (const true_false_string *)&tfs_true_false;
3728                                 if (hfinfo->strings) {
3729                                         tfstring = (const struct true_false_string*) hfinfo->strings;
3730                                 }
3731                                 offset_r += protoo_strlcpy(result+offset_r,
3732                                                            number ?
3733                                                              tfstring->true_string :
3734                                                              tfstring->false_string, size-offset_r);
3735
3736                                 offset_e += protoo_strlcpy(expr+offset_e,
3737                                                            number ? "1" : "0", size-offset_e);
3738                                 break;
3739
3740                         /* XXX - make these just FT_NUMBER? */
3741                         case FT_INT8:
3742                         case FT_INT16:
3743                         case FT_INT24:
3744                         case FT_INT32:
3745                         case FT_UINT8:
3746                         case FT_UINT16:
3747                         case FT_UINT24:
3748                         case FT_UINT32:
3749                         case FT_FRAMENUM:
3750                                 hf_str_val = NULL;
3751                                 number = IS_FT_INT(hfinfo->type) ? 
3752                                                 (guint32) fvalue_get_sinteger(&finfo->value) :
3753                                                 fvalue_get_uinteger(&finfo->value);
3754
3755                                 if ((hfinfo->display & BASE_DISPLAY_E_MASK) == BASE_CUSTOM) {
3756                                         gchar tmp[ITEM_LABEL_LENGTH];
3757                                         custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
3758
3759                                         DISSECTOR_ASSERT(fmtfunc);
3760                                         fmtfunc(tmp, number);
3761
3762                                         offset_r += protoo_strlcpy(result+offset_r, tmp, size-offset_r);
3763
3764                                 } else if (hfinfo->strings) {
3765                                         number_out = hf_str_val = hf_try_val_to_str(number, hfinfo);
3766
3767                                         if (!number_out)
3768                                                 number_out = hfinfo_number_value_format_display(hfinfo, BASE_DEC, number_buf, number);
3769
3770                                         offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
3771
3772                                 } else {
3773                                         number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
3774
3775                                         offset_r += protoo_strlcpy(result+offset_r, number_out, size-offset_r);
3776                                 }
3777
3778                                 if (hf_str_val && (hfinfo->display & BASE_DISPLAY_E_MASK) == BASE_NONE) {
3779                                         g_snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
3780                                 } else {
3781                                         number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
3782
3783                                         g_strlcpy(expr+offset_e, number_out, size-offset_e);
3784                                 }
3785
3786                                 offset_e = (int)strlen(expr);
3787                                 break;
3788
3789                         case FT_INT64:
3790                                 /* XXX: Should handle BASE_CUSTOM ? */
3791                                 g_snprintf(result+offset_r, size-offset_r,
3792                                            "%" G_GINT64_MODIFIER "d",
3793                                            fvalue_get_integer64(&finfo->value));
3794                                 offset_r = (int)strlen(result);
3795                                 break;
3796                         case FT_UINT64:
3797                                 g_snprintf(result+offset_r, size-offset_r,
3798                                 /* XXX: Should handle BASE_CUSTOM ? */
3799                                            "%" G_GINT64_MODIFIER "u",
3800                                            fvalue_get_integer64(&finfo->value));
3801                                 offset_r = (int)strlen(result);
3802                                 break;
3803                         case FT_EUI64:
3804                                 offset_r += protoo_strlcpy(result+offset_r,
3805                                                            eui64_to_str(fvalue_get_integer64(&finfo->value)),
3806                                                            size-offset_r);
3807                                 break;
3808
3809                         case FT_IPv4:
3810                                 ipv4 = (ipv4_addr *)fvalue_get(&finfo->value);
3811                                 n_addr = ipv4_get_net_order_addr(ipv4);
3812                                 offset_r += protoo_strlcpy(result+offset_r,
3813                                                            ip_to_str((guint8 *)&n_addr),
3814                                                            size-offset_r);
3815                                 break;
3816
3817                         case FT_IPv6:
3818                                 ipv6 = (struct e_in6_addr *)fvalue_get(&finfo->value);
3819                                 SET_ADDRESS (&addr, AT_IPv6, sizeof(struct e_in6_addr), ipv6);
3820                                 address_to_str_buf(&addr, result+offset_r, size-offset_r);
3821                                 offset_r = (int)strlen(result);
3822                                 break;
3823
3824                         case FT_ETHER:
3825                                 offset_r += protoo_strlcpy(result+offset_r,
3826                                                            bytes_to_str_punct((const guint8 *)fvalue_get(&finfo->value),
3827                                                                               FT_ETHER_LEN, ':'),
3828                                                            size-offset_r);
3829                                 break;
3830
3831                         case FT_GUID:
3832                                 offset_r += protoo_strlcpy(result+offset_r,
3833                                                            guid_to_str((e_guid_t *)fvalue_get(&finfo->value)),
3834                                                            size-offset_r);
3835                                 break;
3836
3837                         case FT_OID:
3838                                 bytes = (guint8 *)fvalue_get(&finfo->value);
3839                                 offset_r += protoo_strlcpy(result+offset_r,
3840                                                            oid_resolved_from_encoded(bytes,
3841                                                                                      fvalue_length(&finfo->value)),
3842                                                            size-offset_r);
3843                                 offset_e += protoo_strlcpy(expr+offset_e,
3844                                                            oid_encoded2string(bytes, fvalue_length(&finfo->value)),
3845                                                            size-offset_e);
3846                                 break;
3847
3848                         case FT_FLOAT:
3849                                 g_snprintf(result+offset_r, size-offset_r,
3850                                            "%." STRINGIFY(FLT_DIG) "g", fvalue_get_floating(&finfo->value));
3851                                 offset_r = (int)strlen(result);
3852                                 break;
3853
3854                         case FT_DOUBLE:
3855                                 g_snprintf(result+offset_r, size-offset_r,
3856                                            "%." STRINGIFY(DBL_DIG) "g", fvalue_get_floating(&finfo->value));
3857                                 offset_r = (int)strlen(result);
3858                                 break;
3859
3860                         case FT_STRING:
3861                         case FT_STRINGZ:
3862                         case FT_UINT_STRING:
3863                                 bytes = (guint8 *)fvalue_get(&finfo->value);
3864                                 offset_r += protoo_strlcpy(result+offset_r,
3865                                                            format_text(bytes, strlen(bytes)),
3866                                                            size-offset_r);
3867                                 break;
3868
3869                         case FT_IPXNET: /*XXX really No column custom ?*/
3870                         case FT_PCRE:
3871                         default:
3872                                 g_error("hfinfo->type %d (%s) not handled\n",
3873                                                 hfinfo->type,
3874                                                 ftype_name(hfinfo->type));
3875                                 DISSECTOR_ASSERT_NOT_REACHED();
3876                                 break;
3877                         }
3878                         i++;
3879                 }
3880
3881                 switch (hfinfo->type) {
3882
3883                 case FT_BOOLEAN:
3884                 case FT_UINT8:
3885                 case FT_UINT16:
3886                 case FT_UINT24:
3887                 case FT_UINT32:
3888                 case FT_FRAMENUM:
3889                 case FT_INT8:
3890                 case FT_INT16:
3891                 case FT_INT24:
3892                 case FT_INT32:
3893                 case FT_OID:
3894                         /* for these types, "expr" is filled in the loop above */
3895                         break;
3896
3897                 default:
3898                         /* for all others, just copy "result" to "expr" */
3899                         g_strlcpy(expr, result, size);
3900                         break;
3901                 }
3902
3903                 if (!abbrev) {
3904                         /* Store abbrev for return value */
3905                         abbrev = hfinfo->abbrev;
3906                 }
3907
3908                 if (occurrence == 0) {
3909                         /* Fetch next hfinfo with same name (abbrev) */
3910                         hfinfo = hfinfo_same_name_get_prev(hfinfo);
3911                 } else {
3912                         hfinfo = NULL;
3913                 }
3914         }
3915
3916         return abbrev ? abbrev : "";
3917 }
3918
3919
3920 /* Set text of proto_item after having already been created. */
3921 void
3922 proto_item_set_text(proto_item *pi, const char *format, ...)
3923 {
3924         field_info *fi = NULL;
3925         va_list     ap;
3926
3927         if (pi == NULL) {
3928                 return;
3929         }
3930
3931         fi = PITEM_FINFO(pi);
3932         if (fi == NULL)
3933                 return;
3934
3935         if (fi->rep) {
3936                 ITEM_LABEL_FREE(fi->rep);
3937                 fi->rep = NULL;
3938         }
3939
3940         va_start(ap, format);
3941         proto_tree_set_representation(pi, format, ap);
3942         va_end(ap);
3943 }
3944
3945 /* Append to text of proto_item after having already been created. */
3946 void
3947 proto_item_append_text(proto_item *pi, const char *format, ...)
3948 {
3949         field_info *fi = NULL;
3950         size_t      curlen;
3951         va_list     ap;
3952
3953         if (pi == NULL) {
3954                 return;
3955         }
3956
3957         fi = PITEM_FINFO(pi);
3958         if (fi == NULL) {
3959                 return;
3960         }
3961
3962         if (!PROTO_ITEM_IS_HIDDEN(pi)) {
3963                 /*
3964                  * If we don't already have a representation,
3965                  * generate the default representation.
3966                  */
3967                 if (fi->rep == NULL) {
3968                         ITEM_LABEL_NEW(fi->rep);
3969                         proto_item_fill_label(fi, fi->rep->representation);
3970                 }
3971
3972                 curlen = strlen(fi->rep->representation);
3973                 if (ITEM_LABEL_LENGTH > curlen) {
3974                         va_start(ap, format);
3975                         g_vsnprintf(fi->rep->representation + curlen,
3976                                 ITEM_LABEL_LENGTH - (gulong) curlen, format, ap);
3977                         va_end(ap);
3978                 }
3979         }
3980 }
3981
3982 /* Prepend to text of proto_item after having already been created. */
3983 void
3984 proto_item_prepend_text(proto_item *pi, const char *format, ...)
3985 {
3986         field_info *fi = NULL;
3987         char        representation[ITEM_LABEL_LENGTH];
3988         va_list     ap;
3989
3990         if (pi == NULL) {
3991                 return;
3992         }
3993
3994         fi = PITEM_FINFO(pi);
3995         if (fi == NULL) {
3996                 return;
3997         }
3998
3999         if (!PROTO_ITEM_IS_HIDDEN(pi)) {
4000                 /*
4001                  * If we don't already have a representation,
4002                  * generate the default representation.
4003                  */
4004                 if (fi->rep == NULL) {
4005                         ITEM_LABEL_NEW(fi->rep);
4006                         proto_item_fill_label(fi, representation);
4007                 } else
4008                         g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH);
4009
4010                 va_start(ap, format);
4011                 g_vsnprintf(fi->rep->representation,
4012                         ITEM_LABEL_LENGTH, format, ap);
4013                 va_end(ap);
4014                 g_strlcat(fi->rep->representation, representation, ITEM_LABEL_LENGTH);
4015         }
4016 }
4017
4018 void
4019 proto_item_set_len(proto_item *pi, const gint length)
4020 {
4021         field_info *fi;
4022
4023         if (pi == NULL)
4024                 return;
4025
4026         fi = PITEM_FINFO(pi);
4027         if (fi == NULL)
4028                 return;
4029
4030         DISSECTOR_ASSERT(length >= 0);
4031         fi->length = length;
4032
4033         /*
4034          * You cannot just make the "len" field of a GByteArray
4035          * larger, if there's no data to back that length;
4036          * you can only make it smaller.
4037          */
4038         if (fi->value.ftype->ftype == FT_BYTES && length <= (gint)fi->value.value.bytes->len)
4039                 fi->value.value.bytes->len = length;
4040 }
4041
4042 /*
4043  * Sets the length of the item based on its start and on the specified
4044  * offset, which is the offset past the end of the item; as the start
4045  * in the item is relative to the beginning of the data source tvbuff,
4046  * we need to pass in a tvbuff - the end offset is relative to the beginning
4047  * of that tvbuff.
4048  */
4049 void
4050 proto_item_set_end(proto_item *pi, tvbuff_t *tvb, gint end)
4051 {
4052         field_info *fi;
4053
4054         if (pi == NULL)
4055                 return;
4056
4057         fi = PITEM_FINFO(pi);
4058         if (fi == NULL)
4059                 return;
4060
4061         end += tvb_raw_offset(tvb);
4062         DISSECTOR_ASSERT(end >= fi->start);
4063         fi->length = end - fi->start;
4064 }
4065
4066 int
4067 proto_item_get_len(const proto_item *pi)
4068 {
4069         field_info *fi = PITEM_FINFO(pi);
4070         return fi ? fi->length : -1;
4071 }
4072
4073 proto_tree *
4074 proto_tree_create_root(packet_info *pinfo)
4075 {
4076         proto_node *pnode;
4077
4078         /* Initialize the proto_node */
4079         PROTO_NODE_NEW(pnode);
4080         pnode->parent = NULL;
4081         PNODE_FINFO(pnode) = NULL;
4082         pnode->tree_data = g_new(tree_data_t, 1);
4083
4084         /* Make sure we can access pinfo everywhere */
4085         pnode->tree_data->pinfo = pinfo;
4086
4087         /* Don't initialize the tree_data_t. Wait until we know we need it */
4088         pnode->tree_data->interesting_hfids = NULL;
4089
4090         /* Set the default to FALSE so it's easier to
4091          * find errors; if we expect to see the protocol tree
4092          * but for some reason the default 'visible' is not
4093          * changed, then we'll find out very quickly. */
4094         pnode->tree_data->visible = FALSE;
4095
4096         /* Make sure that we fake protocols (if possible) */
4097         pnode->tree_data->fake_protocols = TRUE;
4098
4099         /* Keep track of the number of children */
4100         pnode->tree_data->count = 0;
4101
4102         pnode->tree_data->fi_tmp = NULL;
4103
4104         return (proto_tree *)pnode;
4105 }
4106
4107
4108 /* "prime" a proto_tree with a single hfid that a dfilter
4109  * is interested in. */
4110 void
4111 proto_tree_prime_hfid(proto_tree *tree _U_, const gint hfid)
4112 {
4113         header_field_info *hfinfo;
4114
4115         PROTO_REGISTRAR_GET_NTH(hfid, hfinfo);
4116         /* this field is referenced by a filter so increase the refcount.
4117            also increase the refcount for the parent, i.e the protocol.
4118         */
4119         hfinfo->ref_type = HF_REF_TYPE_DIRECT;
4120         /* only increase the refcount if there is a parent.
4121            if this is a protocol and not a field then parent will be -1
4122            and there is no parent to add any refcounting for.
4123         */
4124         if (hfinfo->parent != -1) {
4125                 header_field_info *parent_hfinfo;
4126                 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
4127
4128                 /* Mark parent as indirectly referenced unless it is already directly
4129                  * referenced, i.e. the user has specified the parent in a filter.
4130                  */
4131                 if (parent_hfinfo->ref_type != HF_REF_TYPE_DIRECT)
4132                         parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
4133         }
4134 }
4135
4136 proto_tree *
4137 proto_item_add_subtree(proto_item *pi,  const gint idx) {
4138         field_info *fi;
4139
4140         if (!pi)
4141                 return NULL;
4142
4143         DISSECTOR_ASSERT(idx >= 0 && idx < num_tree_types);
4144
4145         fi = PITEM_FINFO(pi);
4146         if (!fi)
4147                 return (proto_tree *)pi;
4148
4149         fi->tree_type = idx;
4150
4151         return (proto_tree *)pi;
4152 }
4153
4154 proto_tree *
4155 proto_item_get_subtree(const proto_item *pi) {
4156         field_info *fi;
4157
4158         if (!pi)
4159                 return NULL;
4160         fi = PITEM_FINFO(pi);
4161         if ( (!fi) || (fi->tree_type == -1) )
4162                 return NULL;
4163         return (proto_tree *)pi;
4164 }
4165
4166 proto_item *
4167 proto_item_get_parent(const proto_item *ti) {
4168         if (!ti)
4169                 return NULL;
4170         return ti->parent;
4171 }
4172
4173 proto_item *
4174 proto_item_get_parent_nth(proto_item *ti, int gen) {
4175         if (!ti)
4176                 return NULL;
4177         while (gen--) {
4178                 ti = ti->parent;
4179                 if (!ti)
4180                         return NULL;
4181         }
4182         return ti;
4183 }
4184
4185
4186 proto_item *
4187 proto_tree_get_parent(const proto_tree *tree) {
4188         if (!tree)
4189                 return NULL;
4190         return (proto_item *)tree;
4191 }
4192
4193 proto_tree *
4194 proto_tree_get_root(proto_tree *tree) {
4195         if (!tree)
4196                 return NULL;
4197         while (tree->parent) {
4198                 tree = tree->parent;
4199         }
4200         return tree;
4201 }
4202
4203 void
4204 proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
4205                      proto_item *item_to_move)
4206 {
4207
4208         /* Revert part of: http://anonsvn.wireshark.org/viewvc?view=rev&revision=32443
4209          * See https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=5500
4210          */
4211         /* This function doesn't generate any values. It only reorganizes the prococol tree
4212          * so we can bail out immediately if it isn't visible. */
4213         if (!tree || !PTREE_DATA(tree)->visible)
4214                 return;
4215
4216         DISSECTOR_ASSERT(item_to_move->parent == tree);
4217         DISSECTOR_ASSERT(fixed_item->parent == tree);
4218
4219         /*** cut item_to_move out ***/
4220
4221         /* is item_to_move the first? */
4222         if (tree->first_child == item_to_move) {
4223                 /* simply change first child to next */
4224                 tree->first_child = item_to_move->next;
4225
4226                 DISSECTOR_ASSERT(tree->last_child != item_to_move);
4227         } else {
4228                 proto_item *curr_item;
4229                 /* find previous and change it's next */
4230                 for(curr_item = tree->first_child; curr_item != NULL; curr_item = curr_item->next) {
4231                         if (curr_item->next == item_to_move) {
4232                                 break;
4233                         }
4234                 }
4235
4236                 DISSECTOR_ASSERT(curr_item);
4237
4238                 curr_item->next = item_to_move->next;
4239
4240                 /* fix last_child if required */
4241                 if (tree->last_child == item_to_move) {
4242                         tree->last_child = curr_item;
4243                 }
4244         }
4245
4246         /*** insert to_move after fixed ***/
4247         item_to_move->next = fixed_item->next;
4248         fixed_item->next = item_to_move;
4249         if (tree->last_child == fixed_item) {
4250                 tree->last_child = item_to_move;
4251         }
4252 }
4253
4254 void
4255 proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, gint start,
4256                         const gint length)
4257 {
4258         field_info *fi;
4259
4260         if (tree == NULL)
4261                 return;
4262
4263         fi = PTREE_FINFO(tree);
4264         if (fi == NULL)
4265                 return;
4266
4267         start += tvb_raw_offset(tvb);
4268         DISSECTOR_ASSERT(start >= 0);
4269         DISSECTOR_ASSERT(length >= 0);
4270
4271         fi->appendix_start = start;
4272         fi->appendix_length = length;
4273 }
4274
4275 int
4276 proto_register_protocol(const char *name, const char *short_name,
4277                         const char *filter_name)
4278 {
4279         protocol_t *protocol;
4280         header_field_info *hfinfo;
4281         int proto_id;
4282         char *existing_name;
4283         gint *key;
4284         guint i;
4285         guchar c;
4286         gboolean found_invalid;
4287
4288         /*
4289          * Make sure there's not already a protocol with any of those
4290          * names.  Crash if there is, as that's an error in the code
4291          * or an inappropriate plugin.
4292          * This situation has to be fixed to not register more than one
4293          * protocol with the same name.
4294          *
4295          * This is done by reducing the number of strcmp (and alike) calls
4296          * as much as possible, as this significally slows down startup time.
4297          *
4298          * Drawback: As a hash value is used to reduce insert time,
4299          * this might lead to a hash collision.
4300          * However, although we have somewhat over 1000 protocols, we're using
4301          * a 32 bit int so this is very, very unlikely.
4302          */
4303
4304         key  = (gint *)g_malloc (sizeof(gint));
4305         *key = wrs_str_hash(name);
4306
4307         existing_name = (char *)g_hash_table_lookup(proto_names, key);
4308         if (existing_name != NULL) {
4309                 /* g_error will terminate the program */
4310                 g_error("Duplicate protocol name \"%s\"!"
4311                         " This might be caused by an inappropriate plugin or a development error.", name);
4312         }
4313         g_hash_table_insert(proto_names, key, (gpointer)name);
4314
4315         existing_name = (char *)g_hash_table_lookup(proto_short_names, (gpointer)short_name);
4316         if (existing_name != NULL) {
4317                 g_error("Duplicate protocol short_name \"%s\"!"
4318                         " This might be caused by an inappropriate plugin or a development error.", short_name);
4319         }
4320         g_hash_table_insert(proto_short_names, (gpointer)short_name, (gpointer)short_name);
4321
4322         found_invalid = FALSE;
4323         for (i = 0; filter_name[i]; i++) {
4324                 c = filter_name[i];
4325                 if (!(islower(c) || isdigit(c) || c == '-' || c == '_' || c == '.')) {
4326                         found_invalid = TRUE;
4327                 }
4328         }
4329         if (found_invalid) {
4330                 g_error("Protocol filter name \"%s\" has one or more invalid characters."
4331                         " Allowed are lower characters, digits, '-', '_' and '.'."
4332                         " This might be caused by an inappropriate plugin or a development error.", filter_name);
4333         }
4334         existing_name = (char *)g_hash_table_lookup(proto_filter_names, (gpointer)filter_name);
4335         if (existing_name != NULL) {
4336                 g_error("Duplicate protocol filter_name \"%s\"!"
4337                         " This might be caused by an inappropriate plugin or a development error.", filter_name);
4338         }
4339         g_hash_table_insert(proto_filter_names, (gpointer)filter_name, (gpointer)filter_name);
4340
4341         /* Add this protocol to the list of known protocols; the list
4342            is sorted by protocol short name. */
4343         protocol = g_new(protocol_t, 1);
4344         protocol->name = name;
4345         protocol->short_name = short_name;
4346         protocol->filter_name = filter_name;
4347         protocol->fields = NULL;
4348         protocol->is_enabled = TRUE; /* protocol is enabled by default */
4349         protocol->can_toggle = TRUE;
4350         protocol->is_private = FALSE;
4351         /* list will be sorted later by name, when all protocols completed registering */
4352         protocols = g_list_prepend(protocols, protocol);
4353
4354         /* Here we allocate a new header_field_info struct */
4355         hfinfo = g_slice_new(header_field_info);
4356         hfinfo->name = name;
4357         hfinfo->abbrev = filter_name;
4358         hfinfo->type = FT_PROTOCOL;
4359         hfinfo->display = BASE_NONE;
4360         hfinfo->strings = protocol;
4361         hfinfo->bitmask = 0;
4362         hfinfo->ref_type = HF_REF_TYPE_NONE;
4363         hfinfo->blurb = NULL;
4364         hfinfo->parent = -1; /* this field differentiates protos and fields */
4365
4366         proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
4367         protocol->proto_id = proto_id;
4368         return proto_id;
4369 }
4370
4371 void
4372 proto_mark_private(const int proto_id)
4373 {
4374         protocol_t *protocol = find_protocol_by_id(proto_id);
4375         if (protocol)
4376                 protocol->is_private = TRUE;
4377 }
4378
4379 gboolean
4380 proto_is_private(const int proto_id)
4381 {
4382         protocol_t *protocol = find_protocol_by_id(proto_id);
4383         if (protocol)
4384                 return protocol->is_private;
4385         else
4386                 return FALSE;
4387 }
4388
4389 /*
4390  * Routines to use to iterate over the protocols.
4391  * The argument passed to the iterator routines is an opaque cookie to
4392  * their callers; it's the GList pointer for the current element in
4393  * the list.
4394  * The ID of the protocol is returned, or -1 if there is no protocol.
4395  */
4396 int
4397 proto_get_first_protocol(void **cookie)
4398 {
4399         protocol_t *protocol;
4400
4401         if (protocols == NULL)
4402                 return -1;
4403         *cookie = protocols;
4404         protocol = (protocol_t *)protocols->data;
4405         return protocol->proto_id;
4406 }
4407
4408 int
4409 proto_get_data_protocol(void *cookie)
4410 {
4411         GList *list_item = (GList *)cookie;
4412
4413         protocol_t *protocol = (protocol_t *)list_item->data;
4414         return protocol->proto_id;
4415 }
4416
4417 int
4418 proto_get_next_protocol(void **cookie)
4419 {
4420         GList      *list_item = (GList *)*cookie;
4421         protocol_t *protocol;
4422
4423         list_item = g_list_next(list_item);
4424         if (list_item == NULL)
4425                 return -1;
4426         *cookie = list_item;
4427         protocol = (protocol_t *)list_item->data;
4428         return protocol->proto_id;
4429 }
4430
4431 header_field_info *
4432 proto_get_first_protocol_field(const int proto_id, void **cookie)
4433 {
4434         protocol_t       *protocol = find_protocol_by_id(proto_id);
4435
4436         if ((protocol == NULL) || (protocol->fields == NULL))
4437                 return NULL;
4438
4439         *cookie = protocol->fields;
4440         return (header_field_info *)protocol->fields->data;
4441 }
4442
4443 header_field_info *
4444 proto_get_next_protocol_field(void **cookie)
4445 {
4446         GSList           *list_item = (GSList *)*cookie;
4447
4448         list_item = g_slist_next(list_item);
4449         if (list_item == NULL)
4450                 return NULL;
4451
4452         *cookie = list_item;
4453         return (header_field_info *)list_item->data;
4454 }
4455
4456 protocol_t *
4457 find_protocol_by_id(const int proto_id)
4458 {
4459         header_field_info *hfinfo;
4460
4461         if (proto_id < 0)
4462                 return NULL;
4463
4464         PROTO_REGISTRAR_GET_NTH(proto_id, hfinfo);
4465         DISSECTOR_ASSERT(hfinfo->type == FT_PROTOCOL);
4466         return (protocol_t *)hfinfo->strings;
4467 }
4468
4469 static gint compare_filter_name(gconstpointer proto_arg,
4470                                 gconstpointer filter_name)
4471 {
4472         const protocol_t *protocol = (const protocol_t *)proto_arg;
4473         const gchar      *f_name   = (const gchar *)filter_name;
4474
4475         return (strcmp(protocol->filter_name, f_name));
4476 }
4477
4478 int
4479 proto_get_id(const protocol_t *protocol)
4480 {
4481         return protocol->proto_id;
4482 }
4483
4484 int proto_get_id_by_filter_name(const gchar* filter_name)
4485 {
4486         GList      *list_entry;
4487         protocol_t *protocol;
4488
4489         if(!filter_name){
4490                 fprintf(stderr, "No filter name present");
4491                 DISSECTOR_ASSERT(filter_name);
4492         }
4493
4494         list_entry = g_list_find_custom(protocols, filter_name,
4495                 compare_filter_name);
4496
4497         if (list_entry == NULL)
4498                 return -1;
4499         protocol = (protocol_t *)list_entry->data;
4500         return protocol->proto_id;
4501 }
4502
4503 const char *
4504 proto_get_protocol_name(const int proto_id)
4505 {
4506         protocol_t *protocol;
4507
4508         protocol = find_protocol_by_id(proto_id);
4509
4510         if (protocol == NULL)
4511                 return NULL;
4512         return protocol->name;
4513 }
4514
4515 const char *
4516 proto_get_protocol_short_name(const protocol_t *protocol)
4517 {
4518         if (protocol == NULL)
4519                 return "(none)";
4520         return protocol->short_name;
4521 }
4522
4523 const char *
4524 proto_get_protocol_long_name(const protocol_t *protocol)
4525 {
4526         if (protocol == NULL)
4527                 return "(none)";
4528         return protocol->name;
4529 }
4530
4531 const char *
4532 proto_get_protocol_filter_name(const int proto_id)
4533 {
4534         protocol_t *protocol;
4535
4536         protocol = find_protocol_by_id(proto_id);
4537         if (protocol == NULL)
4538                 return "(none)";
4539         return protocol->filter_name;
4540 }
4541
4542 gboolean
4543 proto_is_protocol_enabled(const protocol_t *protocol)
4544 {
4545         return protocol->is_enabled;
4546 }
4547
4548 gboolean
4549 proto_can_toggle_protocol(const int proto_id)
4550 {
4551         protocol_t *protocol;
4552
4553         protocol = find_protocol_by_id(proto_id);
4554         return protocol->can_toggle;
4555 }
4556
4557 void
4558 proto_set_decoding(const int proto_id, const gboolean enabled)
4559 {
4560         protocol_t *protocol;
4561
4562         protocol = find_protocol_by_id(proto_id);
4563         DISSECTOR_ASSERT(protocol->can_toggle);
4564         protocol->is_enabled = enabled;
4565 }
4566
4567 void
4568 proto_enable_all(void)
4569 {
4570         protocol_t *protocol;
4571         GList      *list_item = protocols;
4572
4573         if (protocols == NULL)
4574                 return;
4575
4576         while (list_item) {
4577                 protocol = (protocol_t *)list_item->data;
4578                 if (protocol->can_toggle)
4579                         protocol->is_enabled = TRUE;
4580                 list_item = g_list_next(list_item);
4581         }
4582 }
4583
4584 void
4585 proto_set_cant_toggle(const int proto_id)
4586 {
4587         protocol_t *protocol;
4588
4589         protocol = find_protocol_by_id(proto_id);
4590         protocol->can_toggle = FALSE;
4591 }
4592
4593 /* for use with static arrays only, since we don't allocate our own copies
4594 of the header_field_info struct contained within the hf_register_info struct */
4595 void
4596 proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
4597 {
4598         int               field_id, i;
4599         hf_register_info *ptr = hf;
4600         protocol_t       *proto;
4601
4602         proto = find_protocol_by_id(parent);
4603         for (i = 0; i < num_records; i++, ptr++) {
4604                 /*
4605                  * Make sure we haven't registered this yet.
4606                  * Most fields have variables associated with them
4607                  * that are initialized to -1; some have array elements,
4608                  * or possibly uninitialized variables, so we also allow
4609                  * 0 (which is unlikely to be the field ID we get back
4610                  * from "proto_register_field_init()").
4611                  */
4612                 if (*ptr->p_id != -1 && *ptr->p_id != 0) {
4613                         fprintf(stderr,
4614                                 "Duplicate field detected in call to proto_register_field_array: %s is already registered\n",
4615                                 ptr->hfinfo.abbrev);
4616                         return;
4617                 }
4618
4619                 if (proto != NULL) {
4620                         if (proto->fields == NULL) {
4621                                 proto->fields = g_slist_append(NULL, &ptr->hfinfo);
4622                                 proto->last_field = proto->fields;
4623                         } else {
4624                                 proto->last_field =
4625                                         g_slist_append(proto->last_field, &ptr->hfinfo)->next;
4626                         }
4627                 }
4628                 field_id = proto_register_field_init(&ptr->hfinfo, parent);
4629                 *ptr->p_id = field_id;
4630         }
4631 }
4632
4633 void
4634 proto_register_fields(const int parent, header_field_info **hfi, const int num_records)
4635 {
4636         int               i;
4637         protocol_t       *proto;
4638
4639         proto = find_protocol_by_id(parent);
4640         for (i = 0; i < num_records; i++) {
4641                 /*
4642                  * Make sure we haven't registered this yet.
4643                  */
4644                 if (hfi[i]->id != -1) {
4645                         fprintf(stderr,
4646                                 "Duplicate field detected in call to proto_register_field_array: %s is already registered\n",
4647                                 hfi[i]->abbrev);
4648                         return;
4649                 }
4650
4651                 if (proto != NULL) {
4652                         if (proto->fields == NULL) {
4653                                 proto->fields = g_slist_append(NULL, hfi[i]);
4654                                 proto->last_field = proto->fields;
4655                         } else {
4656                                 proto->last_field =
4657                                         g_slist_append(proto->last_field, hfi[i])->next;
4658                         }
4659                 }
4660                 proto_register_field_init(hfi[i], parent);
4661         }
4662 }
4663
4664 /* unregister already registered fields */
4665 void
4666 proto_unregister_field (const int parent, gint hf_id)
4667 {
4668         hf_register_info *hf;
4669         protocol_t       *proto;
4670         GSList           *field;
4671
4672         if (hf_id == -1 || hf_id == 0)
4673                 return;
4674
4675         proto = find_protocol_by_id (parent);
4676         if (!proto || !proto->fields) {
4677                 return;
4678         }
4679
4680         for (field = proto->fields; field; field = field->next) {
4681                 hf = (hf_register_info *)field->data;
4682                 if (*hf->p_id == hf_id) {
4683                         /* Found the hf_id in this protocol */
4684                         g_tree_steal (gpa_name_tree, hf->hfinfo.abbrev);
4685                         /* XXX, memleak? g_slist_delete_link() */
4686                         proto->fields = g_slist_remove_link (proto->fields, field);
4687                         proto->last_field = g_slist_last (proto->fields);
4688                         break;
4689                 }
4690         }
4691 }
4692
4693 /* chars allowed in field abbrev */
4694 static
4695 const guchar fld_abbrev_chars[256] = {
4696         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00-0x0F */
4697         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10-0x1F */
4698         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, /* 0x20-0x2F '-', '.'      */
4699         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 0x30-0x3F '0'-'9'       */
4700         0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40-0x4F 'A'-'O'       */
4701         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 0x50-0x5F 'P'-'Z', '_' */
4702         0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x60-0x6F 'a'-'o'       */
4703         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 0x70-0x7F 'p'-'z'       */
4704         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80-0x8F */
4705         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90-0x9F */
4706         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xA0-0xAF */
4707         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xB0-0xBF */
4708         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xC0-0xCF */
4709         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xD0-0xDF */
4710         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xE0-0xEF */
4711         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xF0-0xFF */
4712 };
4713
4714 static const value_string hf_types[] = {
4715         { FT_NONE,          "FT_NONE"          },
4716         { FT_PROTOCOL,      "FT_PROTOCOL"      },
4717         { FT_BOOLEAN,       "FT_BOOLEAN"       },
4718         { FT_UINT8,         "FT_UINT8"         },
4719         { FT_UINT16,        "FT_UINT16"        },
4720         { FT_UINT24,        "FT_UINT24"        },
4721         { FT_UINT32,        "FT_UINT32"        },
4722         { FT_UINT64,        "FT_UINT64"        },
4723         { FT_INT8,          "FT_INT8"          },
4724         { FT_INT16,         "FT_INT16"         },
4725         { FT_INT24,         "FT_INT24"         },
4726         { FT_INT32,         "FT_INT32"         },
4727         { FT_INT64,         "FT_INT64"         },
4728         { FT_EUI64,         "FT_EUI64"         },
4729         { FT_FLOAT,         "FT_FLOAT"         },
4730         { FT_DOUBLE,        "FT_DOUBLE"        },
4731         { FT_ABSOLUTE_TIME, "FT_ABSOLUTE_TIME" },
4732         { FT_RELATIVE_TIME, "FT_RELATIVE_TIME" },
4733         { FT_STRING,        "FT_STRING"        },
4734         { FT_STRINGZ,       "FT_STRINGZ"       },
4735         { FT_UINT_STRING,   "FT_UINT_STRING"   },
4736         { FT_ETHER,         "FT_ETHER"         },
4737         { FT_BYTES,         "FT_BYTES"         },
4738         { FT_UINT_BYTES,    "FT_UINT_BYTES"    },
4739         { FT_IPv4,          "FT_IPv4"          },
4740         { FT_IPv6,          "FT_IPv6"          },
4741         { FT_IPXNET,        "FT_IPXNET"        },
4742         { FT_FRAMENUM,      "FT_FRAMENUM"      },
4743         { FT_PCRE,          "FT_PCR"           },
4744         { FT_GUID,          "FT_GUID"          },
4745         { FT_OID,           "FT_OID"           },
4746         { 0,                NULL } };
4747
4748 static const value_string hf_display[] = {
4749         { BASE_NONE,                      "BASE_NONE"                      },
4750         { BASE_DEC,                       "BASE_DEC"                       },
4751         { BASE_HEX,                       "BASE_HEX"                       },
4752         { BASE_OCT,                       "BASE_OCT"                       },
4753         { BASE_DEC_HEX,                   "BASE_DEC_HEX"                   },
4754         { BASE_HEX_DEC,                   "BASE_HEX_DEC"                   },
4755         { BASE_CUSTOM,                    "BASE_CUSTOM"                    },
4756         { BASE_NONE|BASE_RANGE_STRING,    "BASE_NONE|BASE_RANGE_STRING"    },
4757         { BASE_DEC|BASE_RANGE_STRING,     "BASE_DEC|BASE_RANGE_STRING"     },
4758         { BASE_HEX|BASE_RANGE_STRING,     "BASE_HEX|BASE_RANGE_STRING"     },
4759         { BASE_OCT|BASE_RANGE_STRING,     "BASE_OCT|BASE_RANGE_STRING"     },
4760         { BASE_DEC_HEX|BASE_RANGE_STRING, "BASE_DEC_HEX|BASE_RANGE_STRING" },
4761         { BASE_HEX_DEC|BASE_RANGE_STRING, "BASE_HEX_DEC|BASE_RANGE_STRING" },
4762         { BASE_CUSTOM|BASE_RANGE_STRING,  "BASE_CUSTOM|BASE_RANGE_STRING"  },
4763         { BASE_NONE|BASE_VAL64_STRING,    "BASE_NONE|BASE_VAL64_STRING"    },
4764         { BASE_DEC|BASE_VAL64_STRING,     "BASE_DEC|BASE_VAL64_STRING"     },
4765         { BASE_HEX|BASE_VAL64_STRING,     "BASE_HEX|BASE_VAL64_STRING"     },
4766         { BASE_OCT|BASE_VAL64_STRING,     "BASE_OCT|BASE_VAL64_STRING"     },
4767         { BASE_DEC_HEX|BASE_VAL64_STRING, "BASE_DEC_HEX|BASE_VAL64_STRING" },
4768         { BASE_HEX_DEC|BASE_VAL64_STRING, "BASE_HEX_DEC|BASE_VAL64_STRING" },
4769         { BASE_CUSTOM|BASE_VAL64_STRING,  "BASE_CUSTOM|BASE_VAL64_STRING"  },
4770         { ABSOLUTE_TIME_LOCAL,            "ABSOLUTE_TIME_LOCAL"            },
4771         { ABSOLUTE_TIME_UTC,              "ABSOLUTE_TIME_UTC"              },
4772         { ABSOLUTE_TIME_DOY_UTC,          "ABSOLUTE_TIME_DOY_UTC"          },
4773         { 0,                              NULL } };
4774
4775 /* temporary function containing assert part for easier profiling */
4776 static void
4777 tmp_fld_check_assert(header_field_info *hfinfo)
4778 {
4779
4780         /* The field must have a name (with length > 0) */
4781         if (!hfinfo->name || !hfinfo->name[0]) {
4782                 if (hfinfo->abbrev)
4783                         /* Try to identify the field */
4784                         g_error("Field (abbrev='%s') does not have a name\n",
4785                                 hfinfo->abbrev);
4786                 else
4787                         /* Hum, no luck */
4788                         g_error("Field does not have a name (nor an abbreviation)\n");
4789         }
4790
4791         /* fields with an empty string for an abbreviation aren't filterable */
4792         if (!hfinfo->abbrev || !hfinfo->abbrev[0])
4793                 g_error("Field '%s' does not have an abbreviation\n", hfinfo->name);
4794
4795         /*  These types of fields are allowed to have value_strings,
4796          *  true_false_strings or a protocol_t struct
4797          */
4798         if (hfinfo->strings != NULL && !(
4799                     (hfinfo->type == FT_UINT8)    ||
4800                     (hfinfo->type == FT_UINT16)   ||
4801                     (hfinfo->type == FT_UINT24)   ||
4802                     (hfinfo->type == FT_UINT32)   ||
4803                     (hfinfo->type == FT_UINT64)   ||
4804                     (hfinfo->type == FT_INT8)     ||
4805                     (hfinfo->type == FT_INT16)    ||
4806                     (hfinfo->type == FT_INT24)    ||
4807                     (hfinfo->type == FT_INT32)    ||
4808                     (hfinfo->type == FT_INT64)    ||
4809                     (hfinfo->type == FT_BOOLEAN)  ||
4810                     (hfinfo->type == FT_PROTOCOL) ))
4811                 g_error("Field '%s' (%s) has a 'strings' value but is of type %s"
4812                         " (which is not allowed to have strings)\n",
4813                         hfinfo->name, hfinfo->abbrev,
4814                         val_to_str(hfinfo->type, hf_types, "(Unknown: %d)"));
4815
4816         /* TODO: This check may slow down startup, and output quite a few warnings.
4817            It would be good to be able to enable this (and possibly other checks?)
4818            in non-release builds.   */
4819 #if 0
4820         /* Check for duplicate value_string values.
4821            There are lots that have the same value *and* string, so for now only
4822            report those that have same value but different string. */
4823         if ((hfinfo->strings != NULL) &&
4824             !(hfinfo->display & BASE_RANGE_STRING) &&
4825             !((hfinfo->display & BASE_DISPLAY_E_MASK) == BASE_CUSTOM) &&
4826             (
4827                     (hfinfo->type == FT_UINT8)  ||
4828                     (hfinfo->type == FT_UINT16) ||
4829                     (hfinfo->type == FT_UINT24) ||
4830                     (hfinfo->type == FT_UINT32) ||
4831                     (hfinfo->type == FT_INT8)   ||
4832                     (hfinfo->type == FT_INT16)  ||
4833                     (hfinfo->type == FT_INT24)  ||
4834                     (hfinfo->type == FT_INT32)  ||
4835                     (hfinfo->type == FT_FRAMENUM) )) {
4836
4837                 int n, m;
4838                 const value_string *start_values;
4839                 const value_string *current;
4840
4841             if (hfinfo->display & BASE_EXT_STRING)
4842                         start_values = VALUE_STRING_EXT_VS_P(((const value_string_ext*)hfinfo->strings));
4843                 else
4844                         start_values = (const value_string*)hfinfo->strings;
4845                 current = start_values;
4846
4847                 for (n=0; current; n++, current++) {
4848                         /* Drop out if we reached the end. */
4849                         if ((current->value == 0) && (current->strptr == NULL)) {
4850                                 break;
4851                         }
4852
4853                         /* Check value against all previous */
4854                         for (m=0; m < n; m++) {
4855                                 /* There are lots of duplicates with the same string,
4856                                    so only report if different... */
4857                                 if ((start_values[m].value == current->value) &&
4858                                     (strcmp(start_values[m].strptr, current->strptr) != 0)) {
4859                                         g_warning("Field '%s' (%s) has a conflicting entry in its"
4860                                                   " value_string: %u is at indices %u (%s) and %u (%s))\n",
4861                                                   hfinfo->name, hfinfo->abbrev,
4862                                                   current->value, m, start_values[m].strptr, n, current->strptr);
4863                                 }
4864                         }
4865                 }
4866         }
4867 #endif
4868
4869
4870         switch (hfinfo->type) {
4871
4872                 case FT_INT8:
4873                 case FT_INT16:
4874                 case FT_INT24:
4875                 case FT_INT32:
4876                 case FT_INT64:
4877                         /*      Hexadecimal and octal are, in printf() and everywhere
4878                          *      else, unsigned so don't allow dissectors to register a
4879                          *      signed field to be displayed unsigned.  (Else how would
4880                          *      we display negative values?)
4881                          */
4882                         switch (hfinfo->display & BASE_DISPLAY_E_MASK) {
4883                                 case BASE_HEX:
4884                                 case BASE_OCT:
4885                                 case BASE_DEC_HEX:
4886                                 case BASE_HEX_DEC:
4887                                         g_error("Field '%s' (%s) is signed (%s) but is being displayed unsigned (%s)\n",
4888                                                 hfinfo->name, hfinfo->abbrev,
4889                                                 val_to_str(hfinfo->type, hf_types, "(Unknown: %d)"),
4890                                                 val_to_str(hfinfo->display, hf_display, "(Bit count: %d)"));
4891                         }
4892                         /* FALL THROUGH */
4893                 case FT_UINT8:
4894                 case FT_UINT16:
4895                 case FT_UINT24:
4896                 case FT_UINT32:
4897                 case FT_UINT64:
4898                         /*  Require integral types (other than frame number,
4899                          *  which is always displayed in decimal) to have a
4900                          *  number base.
4901                          *  If there is a strings value then this base is not
4902                          *  normally used except when constructing a display
4903                          *  filter for a value not found in the strings lookup.
4904                          */
4905                         switch (hfinfo->display & BASE_DISPLAY_E_MASK) {
4906                                 case BASE_DEC:
4907                                 case BASE_HEX:
4908                                 case BASE_OCT:
4909                                 case BASE_DEC_HEX:
4910                                 case BASE_HEX_DEC:
4911                                 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
4912                                         break;
4913                                 default:
4914                                         g_error("Field '%s' (%s) is an integral value (%s)"
4915                                                 " but is being displayed as %s\n",
4916                                                 hfinfo->name, hfinfo->abbrev,
4917                                                 val_to_str(hfinfo->type, hf_types, "(Unknown: %d)"),
4918                                                 val_to_str(hfinfo->display, hf_display, "(Unknown: 0x%x)"));
4919                         }
4920                         break;
4921
4922                 case FT_PROTOCOL:
4923                 case FT_FRAMENUM:
4924                         if (hfinfo->display != BASE_NONE)
4925                                 g_error("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE\n",
4926                                         hfinfo->name, hfinfo->abbrev,
4927                                         val_to_str(hfinfo->type, hf_types, "(Unknown: %d)"),
4928                                         val_to_str(hfinfo->display, hf_display, "(Bit count: %d)"));
4929                         if (hfinfo->bitmask != 0)
4930                                 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
4931                                         hfinfo->name, hfinfo->abbrev,
4932                                         val_to_str(hfinfo->type, hf_types, "(Unknown: %d)"));
4933                         break;
4934
4935                 case FT_BOOLEAN:
4936                         break;
4937
4938                 case FT_ABSOLUTE_TIME:
4939                         if (!(hfinfo->display == ABSOLUTE_TIME_LOCAL ||
4940                               hfinfo->display == ABSOLUTE_TIME_UTC   ||
4941                               hfinfo->display == ABSOLUTE_TIME_DOY_UTC))
4942                                 g_error("Field '%s' (%s) is a %s but is being displayed as %s instead of as a time\n",
4943                                         hfinfo->name, hfinfo->abbrev,
4944                                         val_to_str(hfinfo->type, hf_types, "(Unknown: %d)"),
4945                                         val_to_str(hfinfo->display, hf_display, "(Bit count: %d)"));
4946                         if (hfinfo->bitmask != 0)
4947                                 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
4948                                         hfinfo->name, hfinfo->abbrev,
4949                                         val_to_str(hfinfo->type, hf_types, "(Unknown: %d)"));
4950                         break;
4951
4952                 default:
4953                         if (hfinfo->display != BASE_NONE)
4954                                 g_error("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE\n",
4955                                         hfinfo->name, hfinfo->abbrev,
4956                                         val_to_str(hfinfo->type, hf_types, "(Unknown: %d)"),
4957                                         val_to_str(hfinfo->display, hf_display, "(Bit count: %d)"));
4958                         if (hfinfo->bitmask != 0)
4959                                 g_error("Field '%s' (%s) is an %s but has a bitmask\n",
4960                                         hfinfo->name, hfinfo->abbrev,
4961                                         val_to_str(hfinfo->type, hf_types, "(Unknown: %d)"));
4962                         if (hfinfo->strings != NULL)
4963                                 g_error("Field '%s' (%s) is an %s but has a strings value\n",
4964                                         hfinfo->name, hfinfo->abbrev,
4965                                         val_to_str(hfinfo->type, hf_types, "(Unknown: %d)"));
4966                         break;
4967         }
4968 }
4969
4970 #define PROTO_PRE_ALLOC_HF_FIELDS_MEM (120000+PRE_ALLOC_EXPERT_FIELDS_MEM)
4971 static int
4972 proto_register_field_init(header_field_info *hfinfo, const int parent)
4973 {
4974
4975         tmp_fld_check_assert(hfinfo);
4976
4977         hfinfo->parent         = parent;
4978         hfinfo->same_name_next = NULL;
4979         hfinfo->same_name_prev_id = -1;
4980
4981         /* if we always add and never delete, then id == len - 1 is correct */
4982         if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
4983                 if (!gpa_hfinfo.hfi) {
4984                         gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM;
4985                         gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM);
4986                 } else {
4987                         gpa_hfinfo.allocated_len += 1000;
4988                         gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
4989                                                    sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
4990                         /*g_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
4991                 }
4992         }
4993         gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
4994         gpa_hfinfo.len++;
4995         hfinfo->id = gpa_hfinfo.len - 1;
4996
4997         /* if we have real names, enter this field in the name tree */
4998         if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) {
4999
5000                 header_field_info *same_name_next_hfinfo;
5001                 guchar c;
5002
5003                 /* Check that the filter name (abbreviation) is legal;
5004                  * it must contain only alphanumerics, '-', "_", and ".". */
5005                 c = wrs_check_charset(fld_abbrev_chars, hfinfo->abbrev);
5006                 if (c) {
5007                         fprintf(stderr, "Invalid character '%c' in filter name '%s'\n", c, hfinfo->abbrev);
5008                         DISSECTOR_ASSERT(!c);
5009                 }
5010
5011                 /* We allow multiple hfinfo's to be registered under the same
5012                  * abbreviation. This was done for X.25, as, depending
5013                  * on whether it's modulo-8 or modulo-128 operation,
5014                  * some bitfield fields may be in different bits of
5015                  * a byte, and we want to be able to refer to that field
5016                  * with one name regardless of whether the packets
5017                  * are modulo-8 or modulo-128 packets. */
5018
5019                 same_name_hfinfo = NULL;
5020
5021                 g_tree_insert(gpa_name_tree, (gpointer) (hfinfo->abbrev), hfinfo);
5022                 /* GLIB 2.x - if it is already present
5023                  * the previous hfinfo with the same name is saved
5024                  * to same_name_hfinfo by value destroy callback */
5025                 if (same_name_hfinfo) {
5026                         /* There's already a field with this name.
5027                          * Put it after that field in the list of
5028                          * fields with this name, then allow the code
5029                          * after this if{} block to replace the old
5030                          * hfinfo with the new hfinfo in the GTree. Thus,
5031                          * we end up with a linked-list of same-named hfinfo's,
5032                          * with the root of the list being the hfinfo in the GTree */
5033                         same_name_next_hfinfo =
5034                                 same_name_hfinfo->same_name_next;
5035
5036                         hfinfo->same_name_next = same_name_next_hfinfo;
5037                         if (same_name_next_hfinfo)
5038                                 same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
5039
5040                         same_name_hfinfo->same_name_next = hfinfo;
5041                         hfinfo->same_name_prev_id = same_name_hfinfo->id;
5042                 }
5043         }
5044
5045         return hfinfo->id;
5046 }
5047
5048 void
5049 proto_register_subtree_array(gint *const *indices, const int num_indices)
5050 {
5051         int     i;
5052         gint    *const *ptr = indices;
5053
5054         /*
5055          * If we've already allocated the array of tree types, expand
5056          * it; this lets plugins such as mate add tree types after
5057          * the initial startup.  (If we haven't already allocated it,
5058          * we don't allocate it; on the first pass, we just assign
5059          * ett values and keep track of how many we've assigned, and
5060          * when we're finished registering all dissectors we allocate
5061          * the array, so that we do only one allocation rather than
5062          * wasting CPU time and memory by growing the array for each
5063          * dissector that registers ett values.)
5064          */
5065         if (tree_is_expanded != NULL) {
5066                 tree_is_expanded = (guint32 *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(guint32));
5067
5068                 /* set new items to 0 */
5069                 /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of guint32 to 0) */
5070                 for (i = num_tree_types; i < num_tree_types + num_indices; i++)
5071                         tree_is_expanded[i >> 5] &= ~(1 << (i & 31));
5072         }
5073
5074         /*
5075          * Assign "num_indices" subtree numbers starting at "num_tree_types",
5076          * returning the indices through the pointers in the array whose
5077          * first element is pointed to by "indices", and update
5078          * "num_tree_types" appropriately.
5079          */
5080         for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
5081                 if (**ptr != -1) {
5082                         /* g_error will terminate the program */
5083                         g_error("register_subtree_array: subtree item type (ett_...) not -1 !"
5084                                 " This is a development error:"
5085                                 " Either the subtree item type has already been assigned or"
5086                                 " was not initialized to -1.");
5087                 }
5088                 **ptr = num_tree_types;
5089         }
5090 }
5091
5092 static inline gsize
5093 label_concat(char *label_str, gsize pos, const char *str)
5094 {
5095         if (pos < ITEM_LABEL_LENGTH)
5096                 pos += g_strlcpy(label_str + pos, str, ITEM_LABEL_LENGTH - pos);
5097
5098         return pos;
5099 }
5100
5101 static void
5102 label_mark_truncated(char *label_str, gsize name_pos)
5103 {
5104         static const char trunc_str[] = " [truncated]";
5105         const size_t trunc_len = sizeof(trunc_str)-1;
5106
5107         /* ..... field_name: dataaaaaaaaaaaaa
5108          *                 |
5109          *                 ^^^^^ name_pos
5110          *
5111          * ..... field_name [truncated]: dataaaaaaaaaaaaa */
5112
5113         if (name_pos < ITEM_LABEL_LENGTH - trunc_len) {
5114                 memmove(label_str + name_pos + trunc_len, label_str + name_pos, ITEM_LABEL_LENGTH - name_pos - trunc_len);
5115                 memcpy(label_str + name_pos, trunc_str, trunc_len);
5116                 label_str[ITEM_LABEL_LENGTH-1] = '\0';
5117
5118         } else if (name_pos < ITEM_LABEL_LENGTH)
5119                 g_strlcpy(label_str + name_pos, trunc_str, ITEM_LABEL_LENGTH - name_pos);
5120 }
5121
5122 static gsize
5123 label_fill(char *label_str, gsize pos, const header_field_info *hfinfo, const char *text)
5124 {
5125         gsize name_pos;
5126
5127         /* "%s: %s", hfinfo->name, text */
5128         name_pos = pos = label_concat(label_str, pos, hfinfo->name);
5129         pos = label_concat(label_str, pos, ": ");
5130         pos = label_concat(label_str, pos, text ? text : "(null)");
5131
5132         if (pos >= ITEM_LABEL_LENGTH) {
5133                 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
5134                 label_mark_truncated(label_str, name_pos);
5135         }
5136
5137         return pos;
5138 }
5139
5140 static gsize
5141 label_fill_descr(char *label_str, gsize pos, const header_field_info *hfinfo, const char *text, const char *descr)
5142 {
5143         gsize name_pos;
5144
5145         /* "%s: %s (%s)", hfinfo->name, text, descr */
5146         name_pos = pos = label_concat(label_str, pos, hfinfo->name);
5147         pos = label_concat(label_str, pos, ": ");
5148         pos = label_concat(label_str, pos, text ? text : "(null)");
5149         pos = label_concat(label_str, pos, " (");
5150         pos = label_concat(label_str, pos, descr ? descr : "(null)");
5151         pos = label_concat(label_str, pos, ")");
5152
5153         if (pos >= ITEM_LABEL_LENGTH) {
5154                 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
5155                 label_mark_truncated(label_str, name_pos);
5156         }
5157
5158         return pos;
5159 }
5160
5161 void
5162 proto_item_fill_label(field_info *fi, gchar *label_str)
5163 {
5164         header_field_info *hfinfo;
5165         guint8            *bytes;
5166         guint32            integer;
5167         guint64            integer64;
5168         ipv4_addr         *ipv4;
5169         e_guid_t          *guid;
5170         guint32            n_addr; /* network-order IPv4 address */
5171         const gchar       *name;
5172         address            addr;
5173
5174         if (!fi) {
5175                 if (label_str)
5176                         label_str[0]= '\0';
5177                 /* XXX: Check validity of hfinfo->type */
5178                 return;
5179         }
5180
5181         hfinfo = fi->hfinfo;
5182
5183         switch (hfinfo->type) {
5184                 case FT_NONE:
5185                 case FT_PROTOCOL:
5186                         g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH);
5187                         break;
5188
5189                 case FT_BOOLEAN:
5190                         fill_label_boolean(fi, label_str);
5191                         break;
5192
5193                 case FT_BYTES:
5194                 case FT_UINT_BYTES:
5195                         bytes = (guint8 *)fvalue_get(&fi->value);
5196                         label_fill(label_str, 0, hfinfo,
5197                                         (bytes) ? bytes_to_str(bytes, fvalue_length(&fi->value)) : "<MISSING>");
5198                         break;
5199
5200                 /* Four types of integers to take care of:
5201                  *      Bitfield, with val_string
5202                  *      Bitfield, w/o val_string
5203                  *      Non-bitfield, with val_string
5204                  *      Non-bitfield, w/o val_string
5205                  */
5206                 case FT_UINT8:
5207                 case FT_UINT16:
5208                 case FT_UINT24:
5209                 case FT_UINT32:
5210                         if (hfinfo->bitmask) {
5211                                 fill_label_bitfield(fi, label_str);
5212                         } else {
5213                                 fill_label_number(fi, label_str, FALSE);
5214                         }
5215                         break;
5216
5217                 case FT_FRAMENUM:
5218                         fill_label_number(fi, label_str, FALSE);
5219                         break;
5220
5221                 case FT_UINT64:
5222                         fill_label_number64(fi, label_str, FALSE);
5223                         break;
5224
5225                 case FT_INT8:
5226                 case FT_INT16:
5227                 case FT_INT24:
5228                 case FT_INT32:
5229                         DISSECTOR_ASSERT(!hfinfo->bitmask);
5230                         fill_label_number(fi, label_str, TRUE);
5231                         break;
5232
5233                 case FT_INT64:
5234                         fill_label_number64(fi, label_str, TRUE);
5235                         break;
5236
5237                 case FT_FLOAT:
5238                         g_snprintf(label_str, ITEM_LABEL_LENGTH,
5239                                    "%s: %." STRINGIFY(FLT_DIG) "g",
5240                                    hfinfo->name, fvalue_get_floating(&fi->value));
5241                         break;
5242
5243                 case FT_DOUBLE:
5244                         g_snprintf(label_str, ITEM_LABEL_LENGTH,
5245                                    "%s: %." STRINGIFY(DBL_DIG) "g",
5246                                    hfinfo->name, fvalue_get_floating(&fi->value));
5247                         break;
5248
5249                 case FT_ABSOLUTE_TIME:
5250                         label_fill(label_str, 0, hfinfo,
5251                                    abs_time_to_str((const nstime_t *)fvalue_get(&fi->value),
5252                                                 (absolute_time_display_e)hfinfo->display, TRUE));
5253                         break;
5254
5255                 case FT_RELATIVE_TIME:
5256                         g_snprintf(label_str, ITEM_LABEL_LENGTH,
5257                                    "%s: %s seconds", hfinfo->name,
5258                                    rel_time_to_secs_str((const nstime_t *)fvalue_get(&fi->value)));
5259                         break;
5260
5261                 case FT_IPXNET:
5262                         integer = fvalue_get_uinteger(&fi->value);
5263                         g_snprintf(label_str, ITEM_LABEL_LENGTH,
5264                                    "%s: %s (0x%08X)", hfinfo->name,
5265                                    get_ipxnet_name(integer), integer);
5266                         break;
5267
5268                 case FT_AX25:
5269                         bytes = (guint8 *)fvalue_get(&fi->value);
5270                         label_fill_descr(label_str, 0, hfinfo,
5271                                    get_ax25_name(bytes),
5272                                    ax25_to_str(bytes));
5273                         break;
5274
5275                 case FT_VINES:
5276                         addr.type = AT_VINES;
5277                         addr.len  = VINES_ADDR_LEN;
5278                         addr.data = (guint8 *)fvalue_get(&fi->value);
5279
5280                         g_snprintf(label_str, ITEM_LABEL_LENGTH,
5281                                    "%s: %s", hfinfo->name,
5282                                    address_to_str( &addr ));
5283                         break;
5284
5285                 case FT_ETHER:
5286                         bytes = (guint8 *)fvalue_get(&fi->value);
5287                         label_fill_descr(label_str, 0, hfinfo,
5288                                    get_ether_name(bytes),
5289                                    ether_to_str(bytes));
5290                         break;
5291
5292                 case FT_IPv4:
5293                         ipv4 = (ipv4_addr *)fvalue_get(&fi->value);
5294                         n_addr = ipv4_get_net_order_addr(ipv4);
5295                         label_fill_descr(label_str, 0, hfinfo,
5296                                    get_hostname(n_addr),
5297                                    ip_to_str((guint8*)&n_addr));
5298                         break;
5299
5300                 case FT_IPv6:
5301                         bytes = (guint8 *)fvalue_get(&fi->value);
5302                         label_fill_descr(label_str, 0, hfinfo,
5303                                    get_hostname6((struct e_in6_addr *)bytes),
5304                                    ip6_to_str((struct e_in6_addr*)bytes));
5305                         break;
5306
5307                 case FT_GUID:
5308                         guid = (e_guid_t *)fvalue_get(&fi->value);
5309                         label_fill(label_str, 0, hfinfo, guid_to_str(guid));
5310                         break;
5311
5312                 case FT_OID:
5313                         bytes = (guint8 *)fvalue_get(&fi->value);
5314                         name = oid_resolved_from_encoded(bytes, fvalue_length(&fi->value));
5315                         if (name) {
5316                                 label_fill_descr(label_str, 0, hfinfo,
5317                                          oid_encoded2string(bytes, fvalue_length(&fi->value)), name);
5318                         } else {
5319                                 label_fill(label_str, 0, hfinfo,
5320                                          oid_encoded2string(bytes, fvalue_length(&fi->value)));
5321                         }
5322                         break;
5323                 case FT_EUI64:
5324                         integer64 = fvalue_get_integer64(&fi->value);
5325                         label_fill_descr(label_str, 0, hfinfo,
5326                                    get_eui64_name(integer64),
5327                                    eui64_to_str(integer64));
5328                         break;
5329                 case FT_STRING:
5330                 case FT_STRINGZ:
5331                 case FT_UINT_STRING:
5332                         bytes = (guint8 *)fvalue_get(&fi->value);
5333                         label_fill(label_str, 0, hfinfo, format_text(bytes, strlen(bytes)));
5334                         break;
5335
5336                 default:
5337                         g_error("hfinfo->type %d (%s) not handled\n",
5338                                 hfinfo->type, ftype_name(hfinfo->type));
5339                         DISSECTOR_ASSERT_NOT_REACHED();
5340                         break;
5341         }
5342 }
5343
5344 static void
5345 fill_label_boolean(field_info *fi, gchar *label_str)
5346 {
5347         char    *p                    = label_str;
5348         int      bitfield_byte_length = 0, bitwidth;
5349         guint32  unshifted_value;
5350         guint32  value;
5351
5352         header_field_info       *hfinfo   = fi->hfinfo;
5353         const true_false_string *tfstring = (const true_false_string *)&tfs_true_false;
5354
5355         if (hfinfo->strings) {
5356                 tfstring = (const struct true_false_string*) hfinfo->strings;
5357         }
5358
5359         value = fvalue_get_uinteger(&fi->value);
5360         if (hfinfo->bitmask) {
5361                 /* Figure out the bit width */
5362                 bitwidth = hfinfo_bitwidth(hfinfo);
5363
5364                 /* Un-shift bits */
5365                 unshifted_value = value;
5366                 unshifted_value <<= hfinfo_bitshift(hfinfo);
5367
5368                 /* Create the bitfield first */
5369                 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
5370                 bitfield_byte_length = (int) (p - label_str);
5371         }
5372
5373         /* Fill in the textual info */
5374         label_fill(label_str, bitfield_byte_length, hfinfo, value ? tfstring->true_string : tfstring->false_string);
5375 }
5376
5377 static const char *
5378 hf_try_val_to_str(guint32 value, const header_field_info *hfinfo)
5379 {
5380         if (hfinfo->display & BASE_RANGE_STRING)
5381                 return try_rval_to_str(value, (const range_string *) hfinfo->strings);
5382
5383         if (hfinfo->display & BASE_EXT_STRING)
5384                 return try_val_to_str_ext(value, (const value_string_ext *) hfinfo->strings);
5385
5386         if (hfinfo->display & BASE_VAL64_STRING)
5387                 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
5388
5389         return try_val_to_str(value, (const value_string *) hfinfo->strings);
5390 }
5391
5392 static const char *
5393 hf_try_val64_to_str(guint64 value, const header_field_info *hfinfo)
5394 {
5395         if (hfinfo->display & BASE_VAL64_STRING)
5396                 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
5397
5398         /* If this is reached somebody registered a 64-bit field with a 32-bit
5399          * value-string, which isn't right. */
5400         DISSECTOR_ASSERT_NOT_REACHED();
5401
5402         /* This is necessary to squelch MSVC errors; is there
5403            any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
5404            never returns? */
5405         return NULL;
5406 }
5407
5408 static const char *
5409 hf_try_val_to_str_const(guint32 value, const header_field_info *hfinfo, const char *unknown_str)
5410 {
5411         const char *str = hf_try_val_to_str(value, hfinfo);
5412
5413         return (str) ? str : unknown_str;
5414 }
5415
5416 static const char *
5417 hf_try_val64_to_str_const(guint64 value, const header_field_info *hfinfo, const char *unknown_str)
5418 {
5419         const char *str = hf_try_val64_to_str(value, hfinfo);
5420
5421         return (str) ? str : unknown_str;
5422 }
5423
5424 /* Fills data for bitfield ints with val_strings */
5425 static void
5426 fill_label_bitfield(field_info *fi, gchar *label_str)
5427 {
5428         char       *p;
5429         int         bitfield_byte_length, bitwidth;
5430         guint32     unshifted_value;
5431         guint32     value;
5432
5433         char        buf[32];
5434         const char *out;
5435
5436         header_field_info *hfinfo = fi->hfinfo;
5437
5438         /* Figure out the bit width */
5439         bitwidth = hfinfo_bitwidth(hfinfo);
5440
5441         /* Un-shift bits */
5442         unshifted_value = fvalue_get_uinteger(&fi->value);
5443         value = unshifted_value;
5444         if (hfinfo->bitmask) {
5445                 unshifted_value <<= hfinfo_bitshift(hfinfo);
5446         }
5447
5448         /* Create the bitfield first */
5449         p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
5450         bitfield_byte_length = (int) (p - label_str);
5451
5452         /* Fill in the textual info using stored (shifted) value */
5453         if (hfinfo->display == BASE_CUSTOM) {
5454                 gchar tmp[ITEM_LABEL_LENGTH];
5455                 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
5456
5457                 DISSECTOR_ASSERT(fmtfunc);
5458                 fmtfunc(tmp, value);
5459                 label_fill(label_str, bitfield_byte_length, hfinfo, tmp);
5460         }
5461         else if (hfinfo->strings) {
5462                 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
5463
5464                 out = hfinfo_number_vals_format(hfinfo, buf, value);
5465                 if (out == NULL) /* BASE_NONE so don't put integer in descr */
5466                         label_fill(label_str, bitfield_byte_length, hfinfo, val_str);
5467                 else
5468                         label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out);
5469         }
5470         else {
5471                 out = hfinfo_number_value_format(hfinfo, buf, value);
5472
5473                 label_fill(label_str, bitfield_byte_length, hfinfo, out);
5474         }
5475 }
5476
5477 static void
5478 fill_label_number(field_info *fi, gchar *label_str, gboolean is_signed)
5479 {
5480         header_field_info *hfinfo = fi->hfinfo;
5481         guint32            value;
5482
5483         char               buf[32];
5484         const char        *out;
5485
5486         if (is_signed)
5487                 value = fvalue_get_sinteger(&fi->value);
5488         else
5489                 value = fvalue_get_uinteger(&fi->value);
5490
5491         /* Fill in the textual info */
5492         if (hfinfo->display == BASE_CUSTOM) {
5493                 gchar tmp[ITEM_LABEL_LENGTH];
5494                 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
5495
5496                 DISSECTOR_ASSERT(fmtfunc);
5497                 fmtfunc(tmp, value);
5498                 label_fill(label_str, 0, hfinfo, tmp);
5499         }
5500         else if (hfinfo->strings) {
5501                 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
5502
5503                 out = hfinfo_number_vals_format(hfinfo, buf, value);
5504                 if (out == NULL) /* BASE_NONE so don't put integer in descr */
5505                         label_fill(label_str, 0, hfinfo, val_str);
5506                 else
5507                         label_fill_descr(label_str, 0, hfinfo, val_str, out);
5508         }
5509         else {
5510                 out = hfinfo_number_value_format(hfinfo, buf, value);
5511
5512                 label_fill(label_str, 0, hfinfo, out);
5513         }
5514 }
5515
5516 static void
5517 fill_label_number64(field_info *fi, gchar *label_str, gboolean is_signed)
5518 {
5519         const char        *format = NULL;
5520         header_field_info *hfinfo = fi->hfinfo;
5521         guint64            value;
5522         char               tmp[ITEM_LABEL_LENGTH+1];
5523
5524         /* Pick the proper format string */
5525         if (is_signed)
5526                 format = hfinfo_int64_format(hfinfo);
5527         else
5528                 format = hfinfo_uint64_format(hfinfo);
5529
5530         value = fvalue_get_integer64(&fi->value);
5531
5532         /* Format the temporary string */
5533         if (IS_BASE_DUAL(hfinfo->display))
5534                 g_snprintf(tmp, ITEM_LABEL_LENGTH, format, value, value);
5535         else
5536                 g_snprintf(tmp, ITEM_LABEL_LENGTH, format, value);
5537
5538         if (hfinfo->strings) {
5539                 const char *val_str = hf_try_val64_to_str_const(value, hfinfo, "Unknown");
5540
5541                 if ((hfinfo->display & BASE_DISPLAY_E_MASK) == BASE_NONE) {
5542                         label_fill(label_str, 0, hfinfo, val_str);
5543                 }
5544                 else {
5545                         label_fill_descr(label_str, 0, hfinfo, val_str, tmp);
5546                 }
5547         }
5548         else {
5549                 label_fill(label_str, 0, hfinfo, tmp);
5550         }
5551 }
5552
5553 int
5554 hfinfo_bitshift(const header_field_info *hfinfo)
5555 {
5556         const guint32 bitmask = hfinfo->bitmask;
5557
5558 #if defined(__GNUC__) && ((__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
5559         g_assert(bitmask != 0);
5560
5561         return __builtin_ctz(bitmask);
5562 #else
5563         /* From http://graphics.stanford.edu/~seander/bithacks.html#ZerosOnRightMultLookup */
5564         static const int table[32] = {
5565                 0,   1, 28,  2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17,  4, 8,
5566                 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18,  6, 11,  5, 10, 9
5567         };
5568
5569         return table[((guint32)((bitmask & -(gint32)bitmask) * 0x077CB531U)) >> 27];
5570 #endif
5571 }
5572
5573 int
5574 hfinfo_bitwidth(const header_field_info *hfinfo)
5575 {
5576         int bitwidth = 0;
5577
5578         if (!hfinfo->bitmask) {
5579                 return 0;
5580         }
5581
5582         switch (hfinfo->type) {
5583                 case FT_UINT8:
5584                 case FT_INT8:
5585                         bitwidth = 8;
5586                         break;
5587                 case FT_UINT16:
5588                 case FT_INT16:
5589                         bitwidth = 16;
5590                         break;
5591                 case FT_UINT24:
5592                 case FT_INT24:
5593                         bitwidth = 24;
5594                         break;
5595                 case FT_UINT32:
5596                 case FT_INT32:
5597                         bitwidth = 32;
5598                         break;
5599                 case FT_BOOLEAN:
5600                         bitwidth = hfinfo->display; /* hacky? :) */
5601                         break;
5602                 default:
5603                         DISSECTOR_ASSERT_NOT_REACHED();
5604                         ;
5605         }
5606         return bitwidth;
5607 }
5608
5609 static int
5610 _hfinfo_type_hex_octet(int type)
5611 {
5612         switch (type) {
5613                 case FT_INT8:
5614                 case FT_UINT8:
5615                         return 2;
5616
5617                 case FT_UINT16:
5618                 case FT_INT16:
5619                         return 4;
5620
5621                 case FT_UINT24:
5622                 case FT_INT24:
5623                         return 6;
5624
5625                 case FT_UINT32:
5626                 case FT_INT32:
5627                         return 8;
5628
5629                 default:
5630                         DISSECTOR_ASSERT_NOT_REACHED();
5631                         ;
5632         }
5633         return -1;
5634 }
5635
5636 /* private to_str.c API don't export to .h! */
5637 char *oct_to_str_back(char *ptr, guint32 value);
5638 char *hex_to_str_back(char *ptr, int pad, guint32 value);
5639 char *uint_to_str_back(char *ptr, guint32 value);
5640 char *int_to_str_back(char *ptr, gint32 value);
5641
5642 static const char *
5643 hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[32], guint32 value)
5644 {
5645         char *ptr = &buf[31];
5646         gboolean isint = IS_FT_INT(hfinfo->type);
5647
5648         *ptr = '\0';
5649         /* Properly format value */
5650                 switch (display) {
5651                         case BASE_DEC:
5652                                 return isint ? int_to_str_back(ptr, (gint32) value) : uint_to_str_back(ptr, value);
5653
5654                         case BASE_DEC_HEX:
5655                                 *(--ptr) = ')';
5656                                 ptr = hex_to_str_back(ptr, _hfinfo_type_hex_octet(hfinfo->type), value);
5657                                 *(--ptr) = '(';
5658                                 *(--ptr) = ' ';
5659                                 ptr = isint ? int_to_str_back(ptr, (gint32) value) : uint_to_str_back(ptr, value);
5660                                 return ptr;
5661
5662                         case BASE_OCT:
5663                                 return oct_to_str_back(ptr, value);
5664
5665                         case BASE_HEX:
5666                                 return hex_to_str_back(ptr, _hfinfo_type_hex_octet(hfinfo->type), value);
5667
5668                         case BASE_HEX_DEC:
5669                                 *(--ptr) = ')';
5670                                 ptr = isint ? int_to_str_back(ptr, (gint32) value) : uint_to_str_back(ptr, value);
5671                                 *(--ptr) = '(';
5672                                 *(--ptr) = ' ';
5673                                 ptr = hex_to_str_back(ptr, _hfinfo_type_hex_octet(hfinfo->type), value);
5674                                 return ptr;
5675
5676                         default:
5677                                 DISSECTOR_ASSERT_NOT_REACHED();
5678                                 ;
5679                 }
5680         return ptr;
5681 }
5682
5683 static const char *
5684 hfinfo_number_value_format(const header_field_info *hfinfo, char buf[32], guint32 value)
5685 {
5686         int display = hfinfo->display;
5687
5688         if (hfinfo->type == FT_FRAMENUM) {
5689                 /*
5690                  * Frame numbers are always displayed in decimal.
5691                  */
5692                 display = BASE_DEC;
5693         }
5694
5695         return hfinfo_number_value_format_display(hfinfo, display, buf, value);
5696 }
5697
5698 static const char *
5699 hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[32], guint32 value)
5700 {
5701         /* Get the underlying BASE_ value */
5702         int display = hfinfo->display & BASE_DISPLAY_E_MASK;
5703
5704         if (hfinfo->type == FT_FRAMENUM) {
5705                 /*
5706                  * Frame numbers are always displayed in decimal.
5707                  */
5708                 display = BASE_DEC;
5709         }
5710
5711         switch (display) {
5712                 case BASE_NONE:
5713                 /* case BASE_DEC: */
5714                 case BASE_DEC_HEX:
5715                 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
5716                 case BASE_CUSTOM:
5717                         display = BASE_DEC;
5718                         break;
5719
5720                 /* case BASE_HEX: */
5721                 case BASE_HEX_DEC:
5722                         display = BASE_HEX;
5723                         break;
5724         }
5725
5726         return hfinfo_number_value_format_display(hfinfo, display, buf, value);
5727 }
5728
5729 static const char *
5730 hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[32], guint32 value)
5731 {
5732         /* Get the underlying BASE_ value */
5733         int display = hfinfo->display & BASE_DISPLAY_E_MASK;
5734
5735         if (display == BASE_NONE)
5736                 return NULL;
5737
5738         if (display == BASE_DEC_HEX)
5739                 display = BASE_DEC;
5740         if (display == BASE_HEX_DEC)
5741                 display = BASE_HEX;
5742
5743         return hfinfo_number_value_format_display(hfinfo, display, buf, value);
5744 }
5745
5746 static const char *
5747 hfinfo_uint64_format(const header_field_info *hfinfo)
5748 {
5749         const char *format = NULL;
5750
5751         /* Pick the proper format string */
5752         switch (hfinfo->display & BASE_DISPLAY_E_MASK) {
5753                 case BASE_DEC:
5754                         format = "%" G_GINT64_MODIFIER "u";
5755                         break;
5756                 case BASE_DEC_HEX:
5757                         format = "%" G_GINT64_MODIFIER "u (0x%016" G_GINT64_MODIFIER "x)";
5758                         break;
5759                 case BASE_OCT: /* I'm lazy */
5760                         format = "%#" G_GINT64_MODIFIER "o";
5761                         break;
5762                 case BASE_HEX:
5763                         format = "0x%016" G_GINT64_MODIFIER "x";
5764                         break;
5765                 case BASE_HEX_DEC:
5766                         format = "0x%016" G_GINT64_MODIFIER "x (%" G_GINT64_MODIFIER "u)";
5767                         break;
5768                 default:
5769                         DISSECTOR_ASSERT_NOT_REACHED();
5770                         ;
5771         }
5772         return format;
5773 }
5774
5775 static const char *
5776 hfinfo_int64_format(const header_field_info *hfinfo)
5777 {
5778         const char *format = NULL;
5779
5780         /* Pick the proper format string */
5781         switch (hfinfo->display & BASE_DISPLAY_E_MASK) {
5782                 case BASE_DEC:
5783                         format = "%" G_GINT64_MODIFIER "d";
5784                         break;
5785                 case BASE_DEC_HEX:
5786                         format = "%" G_GINT64_MODIFIER "d (0x%016" G_GINT64_MODIFIER "x)";
5787                         break;
5788                 case BASE_OCT: /* I'm lazy */
5789                         format = "%#" G_GINT64_MODIFIER "o";
5790                         break;
5791                 case BASE_HEX:
5792                         format = "0x%016" G_GINT64_MODIFIER "x";
5793                         break;
5794                 case BASE_HEX_DEC:
5795                         format = "0x%016" G_GINT64_MODIFIER "x (%" G_GINT64_MODIFIER "d)";
5796                         break;
5797                 default:
5798                         DISSECTOR_ASSERT_NOT_REACHED();
5799                         ;
5800         }
5801         return format;
5802 }
5803
5804 int
5805 proto_registrar_n(void)
5806 {
5807         return gpa_hfinfo.len;
5808 }
5809
5810 const char *
5811 proto_registrar_get_name(const int n)
5812 {
5813         header_field_info *hfinfo;
5814
5815         PROTO_REGISTRAR_GET_NTH(n, hfinfo);
5816         return hfinfo->name;
5817 }
5818
5819 const char *
5820 proto_registrar_get_abbrev(const int n)
5821 {
5822         header_field_info *hfinfo;
5823
5824         PROTO_REGISTRAR_GET_NTH(n, hfinfo);
5825         return hfinfo->abbrev;
5826 }
5827
5828 enum ftenum
5829 proto_registrar_get_ftype(const int n)
5830 {
5831         header_field_info *hfinfo;
5832
5833         PROTO_REGISTRAR_GET_NTH(n, hfinfo);
5834         return hfinfo->type;
5835 }
5836
5837 int
5838 proto_registrar_get_parent(const int n)
5839 {
5840         header_field_info *hfinfo;
5841
5842         PROTO_REGISTRAR_GET_NTH(n, hfinfo);
5843         return hfinfo->parent;
5844 }
5845
5846 gboolean
5847 proto_registrar_is_protocol(const int n)
5848 {
5849         header_field_info *hfinfo;
5850
5851         PROTO_REGISTRAR_GET_NTH(n, hfinfo);
5852         return (hfinfo->parent == -1 ? TRUE : FALSE);
5853 }
5854
5855 /* Returns length of field in packet (not necessarily the length
5856  * in our internal representation, as in the case of IPv4).
5857  * 0 means undeterminable at time of registration
5858  * -1 means the field is not registered. */
5859 gint
5860 proto_registrar_get_length(const int n)
5861 {
5862         header_field_info *hfinfo;
5863
5864         PROTO_REGISTRAR_GET_NTH(n, hfinfo);
5865         return ftype_length(hfinfo->type);
5866 }
5867
5868 /* Looks for a protocol or a field in a proto_tree. Returns TRUE if
5869  * it exists anywhere, or FALSE if it exists nowhere. */
5870 gboolean
5871 proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
5872 {
5873         GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
5874
5875         if (!ptrs) {
5876                 return FALSE;
5877         }
5878         else if (g_ptr_array_len(ptrs) > 0) {
5879                 return TRUE;
5880         }
5881         else {
5882                 return FALSE;
5883         }
5884 }
5885
5886 /* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
5887  * This only works if the hfindex was "primed" before the dissection
5888  * took place, as we just pass back the already-created GPtrArray*.
5889  * The caller should *not* free the GPtrArray*; proto_tree_free_node()
5890  * handles that. */
5891 GPtrArray *
5892 proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
5893 {
5894         if (!tree)
5895                 return NULL;
5896
5897         if (PTREE_DATA(tree)->interesting_hfids != NULL)
5898                 return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)->interesting_hfids,
5899                                            GINT_TO_POINTER(id));
5900         else
5901                 return NULL;
5902 }
5903
5904 gboolean
5905 proto_tracking_interesting_fields(const proto_tree *tree)
5906 {
5907         if (!tree)
5908                 return FALSE;
5909
5910         return (PTREE_DATA(tree)->interesting_hfids != NULL);
5911 }
5912
5913 /* Helper struct for proto_find_info() and      proto_all_finfos() */
5914 typedef struct {
5915         GPtrArray *array;
5916         int        id;
5917 } ffdata_t;
5918
5919 /* Helper function for proto_find_info() */
5920 static gboolean
5921 find_finfo(proto_node *node, gpointer data)
5922 {
5923         field_info *fi = PNODE_FINFO(node);
5924         if (fi && fi->hfinfo) {
5925                 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
5926                         g_ptr_array_add(((ffdata_t*)data)->array, fi);
5927                 }
5928         }
5929
5930         /* Don't stop traversing. */
5931         return FALSE;
5932 }
5933
5934 /* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
5935 * This works on any proto_tree, primed or unprimed, but actually searches
5936 * the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
5937 * The caller does need to free the returned GPtrArray with
5938 * g_ptr_array_free(<array>, TRUE).
5939 */
5940 GPtrArray *
5941 proto_find_finfo(proto_tree *tree, const int id)
5942 {
5943         ffdata_t ffdata;
5944
5945         ffdata.array = g_ptr_array_new();
5946         ffdata.id = id;
5947
5948         proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
5949
5950         return ffdata.array;
5951 }
5952
5953 /* Helper function for proto_all_finfos() */
5954 static gboolean
5955 every_finfo(proto_node *node, gpointer data)
5956 {
5957         field_info *fi = PNODE_FINFO(node);
5958         if (fi && fi->hfinfo) {
5959                 g_ptr_array_add(((ffdata_t*)data)->array, fi);
5960         }
5961
5962         /* Don't stop traversing. */
5963         return FALSE;
5964 }
5965
5966 /* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree. */
5967 GPtrArray *
5968 proto_all_finfos(proto_tree *tree)
5969 {
5970         ffdata_t ffdata;
5971
5972         ffdata.array = g_ptr_array_new();
5973         ffdata.id = 0;
5974
5975         proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
5976
5977         return ffdata.array;
5978 }
5979
5980
5981 typedef struct {
5982         guint       offset;
5983         field_info *finfo;
5984         tvbuff_t   *tvb;
5985 } offset_search_t;
5986
5987 static gboolean
5988 check_for_offset(proto_node *node, const gpointer data)
5989 {
5990         field_info      *fi        = PNODE_FINFO(node);
5991         offset_search_t *offsearch = (offset_search_t *)data;
5992
5993         /* !fi == the top most container node which holds nothing */
5994         if (fi && !PROTO_ITEM_IS_HIDDEN(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
5995                 if (offsearch->offset >= (guint) fi->start &&
5996                                 offsearch->offset < (guint) (fi->start + fi->length)) {
5997
5998                         offsearch->finfo = fi;
5999                         return FALSE; /* keep traversing */
6000                 }
6001         }
6002         return FALSE; /* keep traversing */
6003 }
6004
6005 /* Search a proto_tree backwards (from leaves to root) looking for the field
6006  * whose start/length occupies 'offset' */
6007 /* XXX - I couldn't find an easy way to search backwards, so I search
6008  * forwards, w/o stopping. Therefore, the last finfo I find will the be
6009  * the one I want to return to the user. This algorithm is inefficient
6010  * and could be re-done, but I'd have to handle all the children and
6011  * siblings of each node myself. When I have more time I'll do that.
6012  * (yeah right) */
6013 field_info *
6014 proto_find_field_from_offset(proto_tree *tree, guint offset, tvbuff_t *tvb)
6015 {
6016         offset_search_t offsearch;
6017
6018         offsearch.offset = offset;
6019         offsearch.finfo  = NULL;
6020         offsearch.tvb    = tvb;
6021
6022         proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
6023
6024         return offsearch.finfo;
6025 }
6026
6027 /* Dumps the protocols in the registration database to stdout.  An independent
6028  * program can take this output and format it into nice tables or HTML or
6029  * whatever.
6030  *
6031  * There is one record per line. The fields are tab-delimited.
6032  *
6033  * Field 1 = protocol name
6034  * Field 2 = protocol short name
6035  * Field 3 = protocol filter name
6036  */
6037 void
6038 proto_registrar_dump_protocols(void)
6039 {
6040         protocol_t *protocol;
6041         int         i;
6042         void       *cookie = NULL;
6043
6044
6045         i = proto_get_first_protocol(&cookie);
6046         while (i != -1) {
6047                 protocol = find_protocol_by_id(i);
6048                 printf("%s\t%s\t%s\n", protocol->name, protocol->short_name,
6049                         protocol->filter_name);
6050                 i = proto_get_next_protocol(&cookie);
6051         }
6052 }
6053
6054 /* Dumps the value_strings, extended value string headers, range_strings
6055  * or true/false strings for fields that have them.
6056  * There is one record per line. Fields are tab-delimited.
6057  * There are four types of records: Value String, Extended Value String Header,
6058  * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
6059  * the type of record.
6060  *
6061  * Note that a record will be generated only if the value_string,... is referenced
6062  * in a registered hfinfo entry.
6063  *
6064  *
6065  * Value Strings
6066  * -------------
6067  * Field 1 = 'V'
6068  * Field 2 = Field abbreviation to which this value string corresponds
6069  * Field 3 = Integer value
6070  * Field 4 = String
6071  *
6072  * Extended Value String Headers
6073  * -----------------------------
6074  * Field 1 = 'E'
6075  * Field 2 = Field abbreviation to which this extended value string header corresponds
6076  * Field 3 = Extended Value String "Name"
6077  * Field 4 = Number of entries in the associated value_string array
6078  * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
6079  *
6080  * Range Strings
6081  * -------------
6082  * Field 1 = 'R'
6083  * Field 2 = Field abbreviation to which this range string corresponds
6084  * Field 3 = Integer value: lower bound
6085  * Field 4 = Integer value: upper bound
6086  * Field 5 = String
6087  *
6088  * True/False Strings
6089  * ------------------
6090  * Field 1 = 'T'
6091  * Field 2 = Field abbreviation to which this true/false string corresponds
6092  * Field 3 = True String
6093  * Field 4 = False String
6094  */
6095 void
6096 proto_registrar_dump_values(void)
6097 {
6098         header_field_info       *hfinfo;
6099         int                     i, len, vi;
6100         const value_string      *vals;
6101         const val64_string      *vals64;
6102         const range_string      *range;
6103         const true_false_string *tfs;
6104
6105         len = gpa_hfinfo.len;
6106         for (i = 0; i < len ; i++) {
6107                 PROTO_REGISTRAR_GET_NTH(i, hfinfo);
6108
6109                  if (hfinfo->id == hf_text_only) {
6110                          continue;
6111                  }
6112
6113                 /* ignore protocols */
6114                 if (proto_registrar_is_protocol(i)) {
6115                         continue;
6116                 }
6117                 /* process header fields */
6118                 else {
6119                         /*
6120                          * If this field isn't at the head of the list of
6121                          * fields with this name, skip this field - all
6122                          * fields with the same name are really just versions
6123                          * of the same field stored in different bits, and
6124                          * should have the same type/radix/value list, and
6125                          * just differ in their bit masks.      (If a field isn't
6126                          * a bitfield, but can be, say, 1 or 2 bytes long,
6127                          * it can just be made FT_UINT16, meaning the
6128                          * *maximum* length is 2 bytes, and be used
6129                          * for all lengths.)
6130                          */
6131                         if (hfinfo->same_name_prev_id != -1)
6132                                 continue;
6133
6134                         vals   = NULL;
6135                         vals64 = NULL;
6136                         range  = NULL;
6137                         tfs    = NULL;
6138
6139                         if (hfinfo->strings != NULL) {
6140                                 if ((hfinfo->display & BASE_DISPLAY_E_MASK) != BASE_CUSTOM &&
6141                                     (hfinfo->type == FT_UINT8  ||
6142                                      hfinfo->type == FT_UINT16 ||
6143                                      hfinfo->type == FT_UINT24 ||
6144                                      hfinfo->type == FT_UINT32 ||
6145                                      hfinfo->type == FT_UINT64 ||
6146                                      hfinfo->type == FT_INT8   ||
6147                                      hfinfo->type == FT_INT16  ||
6148                                      hfinfo->type == FT_INT24  ||
6149                                      hfinfo->type == FT_INT32  ||
6150                                      hfinfo->type == FT_INT64)) {
6151
6152                                         if (hfinfo->display & BASE_EXT_STRING) {
6153                                                 vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings);
6154                                         } else if ((hfinfo->display & BASE_RANGE_STRING) == 0) {
6155                                                 vals = (const value_string *)hfinfo->strings;
6156                                         } else if ((hfinfo->display & BASE_VAL64_STRING) == 0) {
6157                                                 vals64 = (const val64_string *)hfinfo->strings;
6158                                         } else {
6159                                                 range = (const range_string *)hfinfo->strings;
6160                                         }
6161                                 }
6162                                 else if (hfinfo->type == FT_BOOLEAN) {
6163                                         tfs = (const struct true_false_string *)hfinfo->strings;
6164                                 }
6165                         }
6166
6167                         /* Print value strings? */
6168                         if (vals) {
6169                                 if (hfinfo->display & BASE_EXT_STRING) {
6170                                         const value_string_ext *vse_p = (const value_string_ext *)hfinfo->strings;
6171                                         if (!value_string_ext_validate(vse_p)) {
6172                                                 g_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev);
6173                                                 continue;
6174                                         }
6175                                         try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
6176                                         printf("E\t%s\t%d\t%s\t%s\n",
6177                                                hfinfo->abbrev,
6178                                                VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p),
6179                                                VALUE_STRING_EXT_VS_NAME(vse_p),
6180                                                value_string_ext_match_type_str(vse_p));
6181                                 }
6182                                 vi = 0;
6183                                 while (vals[vi].strptr) {
6184                                         /* Print in the proper base */
6185                                         if (hfinfo->display == BASE_HEX) {
6186                                                 printf("V\t%s\t0x%x\t%s\n",
6187                                                        hfinfo->abbrev,
6188                                                        vals[vi].value,
6189                                                        vals[vi].strptr);
6190                                         }
6191                                         else {
6192                                                 printf("V\t%s\t%u\t%s\n",
6193                                                        hfinfo->abbrev,
6194                                                        vals[vi].value,
6195                                                        vals[vi].strptr);
6196                                         }
6197                                         vi++;
6198                                 }
6199                         }
6200                         else if (vals64) {
6201                                 vi = 0;
6202                                 while (vals64[vi].strptr) {
6203                                         printf("V64\t%s\t%" G_GINT64_MODIFIER "u\t%s\n",
6204                                                 hfinfo->abbrev,
6205                                                 vals64[vi].value,
6206                                                 vals64[vi].strptr);
6207                                         vi++;
6208                                 }
6209                         }
6210
6211                         /* print range strings? */
6212                         else if (range) {
6213                                 vi = 0;
6214                                 while (range[vi].strptr) {
6215                                         /* Print in the proper base */
6216                                         if ((hfinfo->display & BASE_DISPLAY_E_MASK) == BASE_HEX) {
6217                                                 printf("R\t%s\t0x%x\t0x%x\t%s\n",
6218                                                        hfinfo->abbrev,
6219                                                        range[vi].value_min,
6220                                                        range[vi].value_max,
6221                                                        range[vi].strptr);
6222                                         }
6223                                         else {
6224                                                 printf("R\t%s\t%u\t%u\t%s\n",
6225                                                        hfinfo->abbrev,
6226                                                        range[vi].value_min,
6227                                                        range[vi].value_max,
6228                                                        range[vi].strptr);
6229                                         }
6230                                         vi++;
6231                                 }
6232                         }
6233
6234                         /* Print true/false strings? */
6235                         else if (tfs) {
6236                                 printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
6237                                        tfs->true_string, tfs->false_string);
6238                         }
6239                 }
6240         }
6241 }
6242
6243 /* Dumps the contents of the registration database to stdout. An independent
6244  * program can take this output and format it into nice tables or HTML or
6245  * whatever.
6246  *
6247  * There is one record per line. Each record is either a protocol or a header
6248  * field, differentiated by the first field. The fields are tab-delimited.
6249  *
6250  * Protocols
6251  * ---------
6252  * Field 1 = 'P'
6253  * Field 2 = descriptive protocol name
6254  * Field 3 = protocol abbreviation
6255  *
6256  * Header Fields
6257  * -------------
6258  * Field 1 = 'F'
6259  * Field 2 = descriptive field name
6260  * Field 3 = field abbreviation
6261  * Field 4 = type ( textual representation of the the ftenum type )
6262  * Field 5 = parent protocol abbreviation
6263  * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
6264  * Field 7 = bitmask: format: hex: 0x....
6265  * Field 8 = blurb describing field
6266  */
6267 void
6268 proto_registrar_dump_fields(void)
6269 {
6270         header_field_info *hfinfo, *parent_hfinfo;
6271         int                i, len;
6272         const char        *enum_name;
6273         const char        *base_name;
6274         const char        *blurb;
6275         char               width[5];
6276
6277         len = gpa_hfinfo.len;
6278         for (i = 0; i < len ; i++) {
6279                 PROTO_REGISTRAR_GET_NTH(i, hfinfo);
6280
6281                 /*
6282                  * Skip the pseudo-field for "proto_tree_add_text()" since
6283                  * we don't want it in the list of filterable fields.
6284                  */
6285                 if (hfinfo->id == hf_text_only)
6286                         continue;
6287
6288                 /* format for protocols */
6289                 if (proto_registrar_is_protocol(i)) {
6290                         printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
6291                 }
6292                 /* format for header fields */
6293                 else {
6294                         /*
6295                          * If this field isn't at the head of the list of
6296                          * fields with this name, skip this field - all
6297                          * fields with the same name are really just versions
6298                          * of the same field stored in different bits, and
6299                          * should have the same type/radix/value list, and
6300                          * just differ in their bit masks.      (If a field isn't
6301                          * a bitfield, but can be, say, 1 or 2 bytes long,
6302                          * it can just be made FT_UINT16, meaning the
6303                          * *maximum* length is 2 bytes, and be used
6304                          * for all lengths.)
6305                          */
6306                         if (hfinfo->same_name_prev_id != -1)
6307                                 continue;
6308
6309                         PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
6310
6311                         enum_name = ftype_name(hfinfo->type);
6312                         base_name = "";
6313
6314                         if (hfinfo->type == FT_UINT8  ||
6315                             hfinfo->type == FT_UINT16 ||
6316                             hfinfo->type == FT_UINT24 ||
6317                             hfinfo->type == FT_UINT32 ||
6318                             hfinfo->type == FT_UINT64 ||
6319                             hfinfo->type == FT_INT8   ||
6320                             hfinfo->type == FT_INT16  ||
6321                             hfinfo->type == FT_INT24  ||
6322                             hfinfo->type == FT_INT32  ||
6323                             hfinfo->type == FT_INT64) {
6324
6325                                 switch (hfinfo->display & BASE_DISPLAY_E_MASK) {
6326                                         case BASE_NONE:
6327                                                 base_name = "BASE_NONE";
6328                                                 break;
6329                                         case BASE_DEC:
6330                                                 base_name = "BASE_DEC";
6331                                                 break;
6332                                         case BASE_HEX:
6333                                                 base_name = "BASE_HEX";
6334                                                 break;
6335                                         case BASE_OCT:
6336                                                 base_name = "BASE_OCT";
6337                                                 break;
6338                                         case BASE_DEC_HEX:
6339                                                 base_name = "BASE_DEC_HEX";
6340                                                 break;
6341                                         case BASE_HEX_DEC:
6342                                                 base_name = "BASE_HEX_DEC";
6343                                                 break;
6344                                         case BASE_CUSTOM:
6345                                                 base_name = "BASE_CUSTOM";
6346                                                 break;
6347                                         default:
6348                                                 base_name = "????";
6349                                                 break;
6350                                 }
6351                         } else if (hfinfo->type == FT_BOOLEAN) {
6352                                 /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
6353                                 g_snprintf(width, sizeof(width), "%d", hfinfo->display);
6354                                 base_name = width;
6355                         }
6356
6357                         blurb = hfinfo->blurb;
6358                         if (blurb == NULL)
6359                                 blurb = "";
6360                         else if (strlen(blurb) == 0)
6361                                 blurb = "\"\"";
6362
6363                         printf("F\t%s\t%s\t%s\t%s\t%s\t0x%x\t%s\n",
6364                                 hfinfo->name, hfinfo->abbrev, enum_name,
6365                                 parent_hfinfo->abbrev, base_name, hfinfo->bitmask, blurb);
6366                 }
6367         }
6368 }
6369
6370 /* Dumps field types and descriptive names to stdout. An independent
6371  * program can take this output and format it into nice tables or HTML or
6372  * whatever.
6373  *
6374  * There is one record per line. The fields are tab-delimited.
6375  *
6376  * Field 1 = field type name, e.g. FT_UINT8
6377  * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
6378  */
6379 void
6380 proto_registrar_dump_ftypes(void)
6381 {
6382         int fte;
6383
6384         for (fte = 0; fte < FT_NUM_TYPES; fte++) {
6385                 printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
6386         }
6387 }
6388
6389 static const char *
6390 hfinfo_numeric_format(const header_field_info *hfinfo)
6391 {
6392         const char *format = NULL;
6393
6394                 /* Get the underlying BASE_ value */
6395                 switch (hfinfo->display & BASE_DISPLAY_E_MASK) {
6396                         case BASE_DEC:
6397                         case BASE_DEC_HEX:
6398                         case BASE_OCT: /* I'm lazy */
6399                         case BASE_CUSTOM:
6400                                 switch (hfinfo->type) {
6401                                         case FT_UINT64:
6402                                                 format = "%s == %" G_GINT64_MODIFIER "u";
6403                                                 break;
6404                                         case FT_INT64:
6405                                                 format = "%s == %" G_GINT64_MODIFIER "d";
6406                                                 break;
6407                                         default:
6408                                                 DISSECTOR_ASSERT_NOT_REACHED();
6409                                                 ;
6410                                 }
6411                                 break;
6412                         case BASE_HEX:
6413                         case BASE_HEX_DEC:
6414                                 switch (hfinfo->type) {
6415                                         case FT_UINT64:
6416                                         case FT_INT64:
6417                                                 format = "%s == 0x%016" G_GINT64_MODIFIER "x";
6418                                                 break;
6419                                         default:
6420                                                 DISSECTOR_ASSERT_NOT_REACHED();
6421                                                 ;
6422                                 }
6423                                 break;
6424                         default:
6425                                 DISSECTOR_ASSERT_NOT_REACHED();
6426                                 ;
6427                 }
6428         return format;
6429 }
6430
6431 /* This function indicates whether it's possible to construct a
6432  * "match selected" display filter string for the specified field,
6433  * returns an indication of whether it's possible, and, if it's
6434  * possible and "filter" is non-null, constructs the filter and
6435  * sets "*filter" to point to it.
6436  * You do not need to [g_]free() this string since it will be automatically
6437  * freed once the next packet is dissected.
6438  */
6439 static gboolean
6440 construct_match_selected_string(field_info *finfo, epan_dissect_t *edt,
6441                                 char **filter)
6442 {
6443         header_field_info *hfinfo;
6444         int                abbrev_len;
6445         char              *ptr;
6446         int                buf_len;
6447         int                dfilter_len, i;
6448         gint               start, length, length_remaining;
6449         guint8             c;
6450         gchar              is_signed_num = FALSE;
6451
6452         if (!finfo)
6453                 return FALSE;
6454
6455         hfinfo     = finfo->hfinfo;
6456         DISSECTOR_ASSERT(hfinfo);
6457         abbrev_len = (int) strlen(hfinfo->abbrev);
6458
6459         if (hfinfo->strings && (hfinfo->display & BASE_DISPLAY_E_MASK) == BASE_NONE) {
6460                 const gchar *str = NULL;
6461
6462                 switch (hfinfo->type) {
6463
6464                 case FT_INT8:
6465                 case FT_INT16:
6466                 case FT_INT24:
6467                 case FT_INT32:
6468                         str = hf_try_val_to_str(fvalue_get_sinteger(&finfo->value), hfinfo);
6469                         break;
6470
6471                 case FT_UINT8:
6472                 case FT_UINT16:
6473                 case FT_UINT24:
6474                 case FT_UINT32:
6475                         str = hf_try_val_to_str(fvalue_get_uinteger(&finfo->value), hfinfo);
6476                         break;
6477
6478                 default:
6479                         break;
6480                 }
6481
6482                 if (str != NULL && filter != NULL) {
6483                         *filter = ep_strdup_printf("%s == \"%s\"", hfinfo->abbrev, str);
6484                         return TRUE;
6485                 }
6486         }
6487
6488         /*
6489          * XXX - we can't use the "val_to_string_repr" and "string_repr_len"
6490          * functions for FT_UINT and FT_INT types, as we choose the base in
6491          * the string expression based on the display base of the field.
6492          *
6493          * Note that the base does matter, as this is also used for
6494          * the protocolinfo tap.
6495          *
6496          * It might be nice to use them in "proto_item_fill_label()"
6497          * as well, although, there, you'd have to deal with the base
6498          * *and* with resolved values for addresses.
6499          *
6500          * Perhaps we need two different val_to_string routines, one
6501          * to generate items for display filters and one to generate
6502          * strings for display, and pass to both of them the
6503          * "display" and "strings" values in the header_field_info
6504          * structure for the field, so they can get the base and,
6505          * if the field is Boolean or an enumerated integer type,
6506          * the tables used to generate human-readable values.
6507          */
6508         switch (hfinfo->type) {
6509
6510                 case FT_INT8:
6511                 case FT_INT16:
6512                 case FT_INT24:
6513                 case FT_INT32:
6514                         is_signed_num = TRUE;
6515                         /* FALLTHRU */
6516                 case FT_UINT8:
6517                 case FT_UINT16:
6518                 case FT_UINT24:
6519                 case FT_UINT32:
6520                 case FT_FRAMENUM:
6521                         if (filter != NULL) {
6522                                 guint32 number;
6523
6524                                 char buf[32];
6525                                 const char *out;
6526
6527                                 if (is_signed_num)
6528                                         number = fvalue_get_sinteger(&finfo->value);
6529                                 else
6530                                         number = fvalue_get_uinteger(&finfo->value);
6531
6532                                 out = hfinfo_numeric_value_format(hfinfo, buf, number);
6533
6534                                 *filter = ep_strdup_printf("%s == %s", hfinfo->abbrev, out);
6535                         }
6536                         break;
6537
6538                 case FT_INT64:
6539                 case FT_UINT64:
6540                         if (filter != NULL) {
6541                                 const char *format = hfinfo_numeric_format(hfinfo);
6542
6543                                 *filter = ep_strdup_printf(format,
6544                                         hfinfo->abbrev,
6545                                         fvalue_get_integer64(&finfo->value));
6546                         }
6547                         break;
6548
6549                 case FT_PROTOCOL:
6550                         if (filter != NULL)
6551                                 *filter = ep_strdup(finfo->hfinfo->abbrev);
6552                         break;
6553
6554                 case FT_NONE:
6555                         /*
6556                          * If the length is 0, just match the name of the
6557                          * field.
6558                          *
6559                          * (Also check for negative values, just in case,
6560                          * as we'll cast it to an unsigned value later.)
6561                          */
6562                         length = finfo->length;
6563                         if (length == 0) {
6564                                 if (filter != NULL)
6565                                         *filter = ep_strdup(finfo->hfinfo->abbrev);
6566                                 break;
6567                         }
6568                         if (length < 0)
6569                                 return FALSE;
6570
6571                         /*
6572                          * This doesn't have a value, so we'd match
6573                          * on the raw bytes at this address.
6574                          *
6575                          * Should we be allowed to access to the raw bytes?
6576                          * If "edt" is NULL, the answer is "no".
6577                          */
6578                         if (edt == NULL)
6579                                 return FALSE;
6580
6581                         /*
6582                          * Is this field part of the raw frame tvbuff?
6583                          * If not, we can't use "frame[N:M]" to match
6584                          * it.
6585                          *
6586                          * XXX - should this be frame-relative, or
6587                          * protocol-relative?
6588                          *
6589                          * XXX - does this fallback for non-registered
6590                          * fields even make sense?
6591                          */
6592                         if (finfo->ds_tvb != edt->tvb)
6593                                 return FALSE;   /* you lose */
6594
6595                         /*
6596                          * Don't go past the end of that tvbuff.
6597                          */
6598                         length_remaining = tvb_length_remaining(finfo->ds_tvb, finfo->start);
6599                         if (length > length_remaining)
6600                                 length = length_remaining;
6601                         if (length <= 0)
6602                                 return FALSE;
6603
6604                         if (filter != NULL) {
6605                                 start = finfo->start;
6606                                 buf_len = 32 + length * 3;
6607                                 *filter = (char *)ep_alloc0(buf_len);
6608                                 ptr = *filter;
6609
6610                                 ptr += g_snprintf(ptr, (gulong) (buf_len-(ptr-*filter)),
6611                                         "frame[%d:%d] == ", finfo->start, length);
6612                                 for (i=0; i<length; i++) {
6613                                         c = tvb_get_guint8(finfo->ds_tvb, start);
6614                                         start++;
6615                                         if (i == 0 ) {
6616                                                 ptr += g_snprintf(ptr, (gulong) (buf_len-(ptr-*filter)), "%02x", c);
6617                                         }
6618                                         else {
6619                                                 ptr += g_snprintf(ptr, (gulong) (buf_len-(ptr-*filter)), ":%02x", c);
6620                                         }
6621                                 }
6622                         }
6623                         break;
6624
6625                 case FT_PCRE:
6626                         /* FT_PCRE never appears as a type for a registered field. It is
6627                          * only used internally. */
6628                         DISSECTOR_ASSERT_NOT_REACHED();
6629                         break;
6630
6631                 /* By default, use the fvalue's "to_string_repr" method. */
6632                 default:
6633                         /* Figure out the string length needed.
6634                          *      The ft_repr length.
6635                          *      4 bytes for " == ".
6636                          *      1 byte for trailing NUL.
6637                          */
6638                         if (filter != NULL) {
6639                                 dfilter_len = fvalue_string_repr_len(&finfo->value,
6640                                                 FTREPR_DFILTER);
6641                                 dfilter_len += abbrev_len + 4 + 1;
6642                                 *filter = (char *)ep_alloc0(dfilter_len);
6643
6644                                 /* Create the string */
6645                                 g_snprintf(*filter, dfilter_len, "%s == ",
6646                                         hfinfo->abbrev);
6647                                 fvalue_to_string_repr(&finfo->value,
6648                                         FTREPR_DFILTER,
6649                                         &(*filter)[abbrev_len + 4]);
6650                         }
6651                         break;
6652         }
6653
6654         return TRUE;
6655 }
6656
6657 /*
6658  * Returns TRUE if we can do a "match selected" on the field, FALSE
6659  * otherwise.
6660  */
6661 gboolean
6662 proto_can_match_selected(field_info *finfo, epan_dissect_t *edt)
6663 {
6664         return construct_match_selected_string(finfo, edt, NULL);
6665 }
6666
6667 /* This function attempts to construct a "match selected" display filter
6668  * string for the specified field; if it can do so, it returns a pointer
6669  * to the string, otherwise it returns NULL.
6670  *
6671  * The string is allocated with packet lifetime scope.
6672  * You do not need to [g_]free() this string since it will be automatically
6673  * freed once the next packet is dissected.
6674  */
6675 char *
6676 proto_construct_match_selected_string(field_info *finfo, epan_dissect_t *edt)
6677 {
6678         char *filter;
6679
6680         if (!construct_match_selected_string(finfo, edt, &filter))
6681                 return NULL;
6682         return filter;
6683 }
6684
6685 /* This function is common code for both proto_tree_add_bitmask() and
6686  *      proto_tree_add_bitmask_text() functions.
6687  */
6688
6689 /* NOTE: to support code written when proto_tree_add_bitmask() and
6690  * proto_tree_add_bitmask_text took a
6691  * gboolean as its last argument, with FALSE meaning "big-endian"
6692  * and TRUE meaning "little-endian", we treat any non-zero value of
6693  * "encoding" as meaning "little-endian".
6694  */
6695 static gboolean
6696 proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
6697                             const int len, const gint ett, const int **fields,
6698                             const guint encoding, const int flags,
6699                             gboolean first)
6700 {
6701         guint32            value = 0;
6702         guint32            available_bits = 0;
6703         guint32            tmpval;
6704         proto_tree        *tree  = NULL;
6705         header_field_info *hf;
6706
6707         switch (len) {
6708                 case 1:
6709                         value = tvb_get_guint8(tvb, offset);
6710                         available_bits = 0xFF;
6711                         break;
6712                 case 2:
6713                         value = encoding ? tvb_get_letohs(tvb, offset) :
6714                         tvb_get_ntohs(tvb, offset);
6715                         available_bits = 0xFFFF;
6716                         break;
6717                 case 3:
6718                         value = encoding ? tvb_get_letoh24(tvb, offset) :
6719                         tvb_get_ntoh24(tvb, offset);
6720                         available_bits = 0xFFFFFF;
6721                         break;
6722                 case 4:
6723                         value = encoding ? tvb_get_letohl(tvb, offset) :
6724                         tvb_get_ntohl(tvb, offset);
6725                         available_bits = 0xFFFFFFFF;
6726                         break;
6727                 default:
6728                         g_assert_not_reached();
6729         }
6730
6731         tree = proto_item_add_subtree(item, ett);
6732         while (*fields) {
6733                 guint32 present_bits;
6734                 hf = proto_registrar_get_nth(**fields);
6735                 DISSECTOR_ASSERT(hf->bitmask != 0);
6736
6737                 /* Skip fields that aren't fully present */
6738                 present_bits = available_bits & hf->bitmask;
6739                 if (present_bits != hf->bitmask) {
6740                         fields++;
6741                         continue;
6742                 }
6743
6744                 proto_tree_add_item(tree, **fields, tvb, offset, len, encoding);
6745                 if (flags & BMT_NO_APPEND) {
6746                         fields++;
6747                         continue;
6748                 }
6749                 tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
6750
6751                 switch (hf->type) {
6752                 case FT_INT8:
6753                 case FT_UINT8:
6754                 case FT_INT16:
6755                 case FT_UINT16:
6756                 case FT_INT24:
6757                 case FT_UINT24:
6758                 case FT_INT32:
6759                 case FT_UINT32:
6760                         if (hf->display == BASE_CUSTOM) {
6761                                 gchar lbl[ITEM_LABEL_LENGTH];
6762                                 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
6763
6764                                 DISSECTOR_ASSERT(fmtfunc);
6765                                 fmtfunc(lbl, tmpval);
6766                                 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
6767                                                 hf->name, lbl);
6768                                 first = FALSE;
6769                         }
6770                         else if (hf->strings) {
6771                                 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
6772                                                        hf->name, hf_try_val_to_str_const(tmpval, hf, "Unknown"));
6773                                 first = FALSE;
6774                         }
6775                         else if (!(flags & BMT_NO_INT)) {
6776                                 char buf[32];
6777                                 const char *out;
6778
6779                                 if (!first) {
6780                                         proto_item_append_text(item, ", ");
6781                                 }
6782
6783                                 out = hfinfo_number_value_format(hf, buf, tmpval);
6784                                 proto_item_append_text(item, "%s: %s", hf->name, out);
6785                                 first = FALSE;
6786                         }
6787
6788                         break;
6789                 case FT_BOOLEAN:
6790                         if (hf->strings && !(flags & BMT_NO_TFS)) {
6791                                 /* If we have true/false strings, emit full - otherwise messages
6792                                    might look weird */
6793                                 const struct true_false_string *tfs =
6794                                         (const struct true_false_string *)hf->strings;
6795
6796                                 if (tmpval) {
6797                                         proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
6798                                                         hf->name, tfs->true_string);
6799                                         first = FALSE;
6800                                 } else if (!(flags & BMT_NO_FALSE)) {
6801                                         proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
6802                                                         hf->name, tfs->false_string);
6803                                         first = FALSE;
6804                                 }
6805                         } else if (hf->bitmask & value) {
6806                                 /* If the flag is set, show the name */
6807                                 proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
6808                                 first = FALSE;
6809                         }
6810                         break;
6811                 default:
6812                         g_assert_not_reached();
6813                 }
6814
6815                 fields++;
6816         }
6817
6818         return first;
6819 }
6820
6821 /* This function will dissect a sequence of bytes that describe a
6822  * bitmask.
6823  * hf_hdr is a 8/16/24/32 bit integer that describes the bitmask to be dissected.
6824  * This field will form an expansion under which the individual fields of the
6825  * bitmask is dissected and displayed.
6826  * This field must be of the type FT_[U]INT{8|16|24|32}.
6827  *
6828  * fields is an array of pointers to int that lists all the fields of the
6829  * bitmask. These fields can be either of the type FT_BOOLEAN for flags
6830  * or another integer of the same type/size as hf_hdr with a mask specified.
6831  * This array is terminated by a NULL entry.
6832  *
6833  * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
6834  * FT_integer fields that have a value_string attached will have the
6835  * matched string displayed on the expansion line.
6836  */
6837 proto_item *
6838 proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
6839                        const guint offset, const int hf_hdr,
6840                        const gint ett, const int **fields,
6841                        const guint encoding)
6842 {
6843         proto_item        *item = NULL;
6844         header_field_info *hf;
6845         int                len;
6846
6847         hf = proto_registrar_get_nth(hf_hdr);
6848         DISSECTOR_ASSERT(IS_FT_INT(hf->type) || IS_FT_UINT(hf->type));
6849         len = ftype_length(hf->type);
6850
6851         if (parent_tree) {
6852                 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
6853                 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields, encoding,
6854                                             BMT_NO_INT|BMT_NO_TFS, FALSE);
6855         }
6856
6857         return item;
6858 }
6859
6860 /* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
6861  * This is intended to support bitmask fields whose lengths can vary, perhaps
6862  * as the underlying standard evolves over time.
6863  * With this API there is the possibility of being called to display more or
6864  * less data than the dissector was coded to support.
6865  * In such cases, it is assumed that bitmasks are extended on the MSb end.
6866  * Thus when presented with "too much" or "too little" data, MSbits will be
6867  * ignored or MSfields sacrificed.
6868  *
6869  * Only fields for which all defined bits are available are displayed.
6870  */
6871 proto_item *
6872 proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
6873                        const guint offset,  const guint len, const int hf_hdr,
6874                        const gint ett, const int **fields,
6875                        const guint encoding)
6876 {
6877         proto_item        *item = NULL;
6878         header_field_info *hf;
6879
6880         hf = proto_registrar_get_nth(hf_hdr);
6881         DISSECTOR_ASSERT(IS_FT_INT(hf->type) || IS_FT_UINT(hf->type));
6882
6883         if (parent_tree) {
6884                 guint   decodable_len;
6885                 guint   decodable_offset;
6886                 guint32 decodable_value;
6887
6888                 decodable_offset = offset;
6889                 decodable_len = MIN(len, (guint) ftype_length(hf->type));
6890
6891                 /* If we are ftype_length-limited,
6892                  * make sure we decode as many LSBs as possible.
6893                  */
6894                 if (encoding == ENC_BIG_ENDIAN) {
6895                         decodable_offset += (len - decodable_len);
6896                 }
6897
6898                 decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
6899                                                  decodable_len, encoding);
6900
6901                 /* The root item covers all the bytes even if we can't decode them all */
6902                 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
6903                                            decodable_value);
6904
6905                 if (decodable_len < len) {
6906                         /* Dissector likely requires updating for new protocol revision */
6907                         expert_add_info_format(NULL, item, PI_UNDECODED, PI_WARN,
6908                                                "Only least-significant %d of %d bytes decoded",
6909                                                decodable_len, len);
6910                 }
6911
6912                 proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
6913                                             ett, fields, encoding, BMT_NO_INT|BMT_NO_TFS, FALSE);
6914         }
6915
6916         return item;
6917 }
6918
6919 /* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
6920 proto_item *
6921 proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
6922                             const guint offset, const guint len,
6923                             const char *name, const char *fallback,
6924                             const gint ett, const int **fields,
6925                             const guint encoding, const int flags)
6926 {
6927         proto_item *item = NULL;
6928
6929         if (parent_tree) {
6930                 item = proto_tree_add_text(parent_tree, tvb, offset, len, "%s", name ? name : "");
6931                 if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields, encoding,
6932                                         flags, TRUE) && fallback) {
6933                         /* Still at first item - append 'fallback' text if any */
6934                         proto_item_append_text(item, "%s", fallback);
6935                 }
6936         }
6937
6938         return item;
6939 }
6940
6941 proto_item *
6942 proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
6943                          const guint bit_offset, const gint no_of_bits,
6944                          const guint encoding)
6945 {
6946         header_field_info *hfinfo;
6947         gint              octet_length;
6948         gint              octet_offset;
6949
6950         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
6951
6952         octet_length = (no_of_bits + 7) >> 3;
6953         octet_offset = bit_offset >> 3;
6954         test_length(hfinfo, tree, tvb, octet_offset, octet_length, encoding);
6955
6956         /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
6957          * but only after doing a bunch more work (which we can, in the common
6958          * case, shortcut here).
6959          */
6960         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
6961
6962         return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL, encoding);
6963 }
6964
6965 /*
6966  * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
6967  * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
6968  * Offset should be given in bits from the start of the tvb.
6969  */
6970
6971 static proto_item *
6972 _proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
6973                             const guint bit_offset, const gint no_of_bits,
6974                             guint64 *return_value, const guint encoding)
6975 {
6976         gint     offset;
6977         guint    length;
6978         guint8   tot_no_bits;
6979         char    *bf_str;
6980         char     lbl_str[ITEM_LABEL_LENGTH];
6981         guint64  value = 0;
6982
6983         proto_item        *pi;
6984         header_field_info *hf_field;
6985
6986         const true_false_string *tfstring;
6987
6988         /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
6989         PROTO_REGISTRAR_GET_NTH(hfindex, hf_field);
6990
6991         if (hf_field->bitmask != 0) {
6992                 REPORT_DISSECTOR_BUG(ep_strdup_printf("Incompatible use of proto_tree_add_bits_ret_val"
6993                                                       " with field '%s' (%s) with bitmask != 0",
6994                                                       hf_field->abbrev, hf_field->name));
6995         }
6996
6997         DISSECTOR_ASSERT(no_of_bits >  0);
6998
6999         /* Byte align offset */
7000         offset = bit_offset>>3;
7001
7002         /*
7003          * Calculate the number of octets used to hold the bits
7004          */
7005         tot_no_bits = ((bit_offset&0x7) + no_of_bits);
7006         length = (tot_no_bits + 7) >> 3;
7007
7008         if (no_of_bits < 65) {
7009                 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
7010         } else {
7011                 DISSECTOR_ASSERT_NOT_REACHED();
7012                 return NULL;
7013         }
7014
7015         /* Sign extend for signed types */
7016         switch (hf_field->type) {
7017                 case FT_INT8:
7018                 case FT_INT16:
7019                 case FT_INT24:
7020                 case FT_INT32:
7021                 case FT_INT64:
7022                         if (value & (G_GINT64_CONSTANT(1) << (no_of_bits-1)))
7023                                 value |= (G_GINT64_CONSTANT(-1) << no_of_bits);
7024                         break;
7025
7026                 default:
7027                         break;
7028         }
7029
7030         if (return_value) {
7031                 *return_value = value;
7032         }
7033
7034         /* Coast clear. Try and fake it */
7035         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
7036
7037         bf_str = decode_bits_in_field(bit_offset, no_of_bits, value);
7038
7039         switch (hf_field->type) {
7040         case FT_BOOLEAN:
7041                 /* Boolean field */
7042                 tfstring = (const true_false_string *) &tfs_true_false;
7043                 if (hf_field->strings)
7044                         tfstring = (const true_false_string *)hf_field->strings;
7045                 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, (guint32)value,
7046                         "%s = %s: %s",
7047                         bf_str, hf_field->name,
7048                         (guint32)value ? tfstring->true_string : tfstring->false_string);
7049                 break;
7050
7051         case FT_UINT8:
7052         case FT_UINT16:
7053         case FT_UINT24:
7054         case FT_UINT32:
7055                 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (guint32)value);
7056                 fill_label_number(PITEM_FINFO(pi), lbl_str, FALSE);
7057                 break;
7058
7059         case FT_INT8:
7060         case FT_INT16:
7061         case FT_INT24:
7062         case FT_INT32:
7063                 pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (gint32)value);
7064                 fill_label_number(PITEM_FINFO(pi), lbl_str, TRUE);
7065                 break;
7066
7067         case FT_UINT64:
7068                 pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
7069                 fill_label_number64(PITEM_FINFO(pi), lbl_str, FALSE);
7070                 break;
7071
7072         case FT_INT64:
7073                 pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (gint64)value);
7074                 fill_label_number64(PITEM_FINFO(pi), lbl_str, TRUE);
7075                 break;
7076
7077         default:
7078                 DISSECTOR_ASSERT_NOT_REACHED();
7079                 return NULL;
7080                 break;
7081         }
7082
7083         proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
7084         return pi;
7085 }
7086
7087 proto_item *
7088 proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
7089                                        const guint bit_offset, const crumb_spec_t *crumb_spec,
7090                                        guint64 *return_value)
7091 {
7092         proto_item *pi;
7093         gint        no_of_bits;
7094         gint        octet_offset;
7095         guint       mask_initial_bit_offset;
7096         guint       mask_greatest_bit_offset;
7097         guint       octet_length;
7098         guint8      i;
7099         char       *bf_str;
7100         char        lbl_str[ITEM_LABEL_LENGTH];
7101         guint64     value;
7102         guint64     composite_bitmask;
7103         guint64     composite_bitmap;
7104
7105         header_field_info       *hf_field;
7106         const true_false_string *tfstring;
7107
7108         /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
7109         PROTO_REGISTRAR_GET_NTH(hfindex, hf_field);
7110
7111         if (hf_field->bitmask != 0) {
7112                 REPORT_DISSECTOR_BUG(ep_strdup_printf(
7113                                              "Incompatible use of proto_tree_add_split_bits_item_ret_val"
7114                                              " with field '%s' (%s) with bitmask != 0",
7115                                              hf_field->abbrev, hf_field->name));
7116         }
7117
7118         mask_initial_bit_offset = bit_offset % 8;
7119
7120         no_of_bits = 0;
7121         value      = 0;
7122         i          = 0;
7123         mask_greatest_bit_offset = 0;
7124         composite_bitmask        = 0;
7125         composite_bitmap         = 0;
7126
7127         while (crumb_spec[i].crumb_bit_length != 0) {
7128                 guint64 crumb_mask, crumb_value;
7129                 guint8  crumb_end_bit_offset;
7130
7131                 DISSECTOR_ASSERT(i < 64);
7132                 crumb_value = tvb_get_bits64(tvb,
7133                                              bit_offset + crumb_spec[i].crumb_bit_offset,
7134                                              crumb_spec[i].crumb_bit_length,
7135                                              ENC_BIG_ENDIAN);
7136                 value      += crumb_value;
7137                 no_of_bits += crumb_spec[i].crumb_bit_length;
7138
7139                 /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
7140                    octet containing the initial offset.
7141                    If the mask is beyond 32 bits, then give up on bit map display.
7142                    This could be improved in future, probably showing a table
7143                    of 32 or 64 bits per row */
7144                 if (mask_greatest_bit_offset < 32) {
7145                         crumb_end_bit_offset = mask_initial_bit_offset
7146                                 + crumb_spec[i].crumb_bit_offset
7147                                 + crumb_spec[i].crumb_bit_length;
7148                         crumb_mask = (G_GUINT64_CONSTANT(1) << crumb_spec[i].crumb_bit_length) - 1;
7149
7150                         if (crumb_end_bit_offset > mask_greatest_bit_offset) {
7151                                 mask_greatest_bit_offset = crumb_end_bit_offset;
7152                         }
7153                         composite_bitmask |= (crumb_mask  << (64 - crumb_end_bit_offset));
7154                         composite_bitmap  |= (crumb_value << (64 - crumb_end_bit_offset));
7155                 }
7156                 /* Shift left for the next segment */
7157                 value <<= crumb_spec[++i].crumb_bit_length;
7158         }
7159
7160         /* Sign extend for signed types */
7161         switch (hf_field->type) {
7162                 case FT_INT8:
7163                 case FT_INT16:
7164                 case FT_INT24:
7165                 case FT_INT32:
7166                 case FT_INT64:
7167                         if (no_of_bits && (value & (G_GINT64_CONSTANT(1) << (no_of_bits-1))))
7168                                 value |= (G_GINT64_CONSTANT(-1) << no_of_bits);
7169                         break;
7170                 default:
7171                         break;
7172         }
7173
7174         if (return_value) {
7175                 *return_value = value;
7176         }
7177
7178         /* Coast clear. Try and fake it */
7179         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
7180
7181         /* initialise the format string */
7182         bf_str    = (char *)ep_alloc(256);
7183         bf_str[0] = '\0';
7184
7185         octet_offset = bit_offset >> 3;
7186
7187         /* Round up mask length to nearest octet */
7188         octet_length = ((mask_greatest_bit_offset + 7) >> 3);
7189         mask_greatest_bit_offset = octet_length << 3;
7190
7191         /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
7192            It would be a useful enhancement to eliminate this restriction. */
7193         if (mask_greatest_bit_offset <= 32) {
7194                 other_decode_bitfield_value(bf_str,
7195                                             (guint32)(composite_bitmap  >> (64 - mask_greatest_bit_offset)),
7196                                             (guint32)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
7197                                             mask_greatest_bit_offset);
7198         }
7199
7200         switch (hf_field->type) {
7201         case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
7202                 /* Boolean field */
7203                 tfstring = (const true_false_string *) &tfs_true_false;
7204                 if (hf_field->strings)
7205                         tfstring = (const true_false_string *) hf_field->strings;
7206                 return proto_tree_add_boolean_format(tree, hfindex,
7207                                                      tvb, octet_offset, octet_length, (guint32)value,
7208                                                      "%s = %s: %s",
7209                                                      bf_str, hf_field->name,
7210                                                      (guint32)value ? tfstring->true_string : tfstring->false_string);
7211                 break;
7212
7213         case FT_UINT8:
7214         case FT_UINT16:
7215         case FT_UINT24:
7216         case FT_UINT32:
7217                 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (guint32)value);
7218                 fill_label_number(PITEM_FINFO(pi), lbl_str, FALSE);
7219                 break;
7220
7221         case FT_INT8:
7222         case FT_INT16:
7223         case FT_INT24:
7224         case FT_INT32:
7225                 pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (gint32)value);
7226                 fill_label_number(PITEM_FINFO(pi), lbl_str, TRUE);
7227                 break;
7228
7229         case FT_UINT64:
7230                 pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
7231                 fill_label_number64(PITEM_FINFO(pi), lbl_str, FALSE);
7232                 break;
7233
7234         case FT_INT64:
7235                 pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (gint64)value);
7236                 fill_label_number64(PITEM_FINFO(pi), lbl_str, TRUE);
7237                 break;
7238
7239         default:
7240                 DISSECTOR_ASSERT_NOT_REACHED();
7241                 return NULL;
7242                 break;
7243         }
7244         proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
7245         return pi;
7246 }
7247
7248 void
7249 proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const guint bit_offset,
7250                                 const crumb_spec_t *crumb_spec, guint16 crumb_index)
7251 {
7252         header_field_info *hfinfo;
7253
7254         PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
7255         proto_tree_add_text(tree, tvb,
7256                             bit_offset >> 3,
7257                             ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1,
7258                             "%s crumb %d of %s (decoded above)",
7259                             decode_bits_in_field(bit_offset, crumb_spec[crumb_index].crumb_bit_length,
7260                                                  tvb_get_bits(tvb,
7261                                                               bit_offset,
7262                                                               crumb_spec[crumb_index].crumb_bit_length,
7263                                                               ENC_BIG_ENDIAN)),
7264                             crumb_index,
7265                             hfinfo->name);
7266 }
7267
7268 proto_item *
7269 proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
7270                             const guint bit_offset, const gint no_of_bits,
7271                             guint64 *return_value, const guint encoding)
7272 {
7273         proto_item *item;
7274
7275         if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
7276                                                  bit_offset, no_of_bits,
7277                                                  return_value, encoding))) {
7278                 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset));
7279                 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_SIZE(no_of_bits));
7280         }
7281         return item;
7282 }
7283
7284 static proto_item *
7285 _proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
7286                                  tvbuff_t *tvb, const guint bit_offset,
7287                                  const gint no_of_bits, void *value_ptr,
7288                                  gchar *value_str)
7289 {
7290         gint     offset;
7291         guint    length;
7292         guint8   tot_no_bits;
7293         char    *str;
7294         guint64  value = 0;
7295         header_field_info *hf_field;
7296
7297         /* We do not have to return a value, try to fake it as soon as possible */
7298         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
7299
7300         if (hf_field->bitmask != 0) {
7301                 REPORT_DISSECTOR_BUG(ep_strdup_printf(
7302                                              "Incompatible use of proto_tree_add_bits_format_value"
7303                                              " with field '%s' (%s) with bitmask != 0",
7304                                              hf_field->abbrev, hf_field->name));
7305         }
7306
7307         DISSECTOR_ASSERT(no_of_bits > 0);
7308
7309         /* Byte align offset */
7310         offset = bit_offset>>3;
7311
7312         /*
7313          * Calculate the number of octets used to hold the bits
7314          */
7315         tot_no_bits = ((bit_offset&0x7) + no_of_bits);
7316         length      = tot_no_bits>>3;
7317         /* If we are using part of the next octet, increase length by 1 */
7318         if (tot_no_bits & 0x07)
7319                 length++;
7320
7321         if (no_of_bits < 65) {
7322                 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, ENC_BIG_ENDIAN);
7323         } else {
7324                 DISSECTOR_ASSERT_NOT_REACHED();
7325                 return NULL;
7326         }
7327
7328         str = decode_bits_in_field(bit_offset, no_of_bits, value);
7329
7330         strcat(str, " = ");
7331         strcat(str, hf_field->name);
7332
7333         /*
7334          * This function does not receive an actual value but a dimensionless pointer to that value.
7335          * For this reason, the type of the header field is examined in order to determine
7336          * what kind of value we should read from this address.
7337          * The caller of this function must make sure that for the specific header field type the address of
7338          * a compatible value is provided.
7339          */
7340         switch (hf_field->type) {
7341         case FT_BOOLEAN:
7342                 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(guint32 *)value_ptr,
7343                                                      "%s: %s", str, value_str);
7344                 break;
7345
7346         case FT_UINT8:
7347         case FT_UINT16:
7348         case FT_UINT24:
7349         case FT_UINT32:
7350                 return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(guint32 *)value_ptr,
7351                                                   "%s: %s", str, value_str);
7352                 break;
7353
7354         case FT_UINT64:
7355                 return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(guint64 *)value_ptr,
7356                                                     "%s: %s", str, value_str);
7357                 break;
7358
7359         case FT_INT8:
7360         case FT_INT16:
7361         case FT_INT24:
7362         case FT_INT32:
7363                 return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(gint32 *)value_ptr,
7364                                                  "%s: %s", str, value_str);
7365                 break;
7366
7367         case FT_INT64:
7368                 return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(gint64 *)value_ptr,
7369                                                    "%s: %s", str, value_str);
7370                 break;
7371
7372         case FT_FLOAT:
7373                 return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
7374                                                    "%s: %s", str, value_str);
7375                 break;
7376
7377         default:
7378                 DISSECTOR_ASSERT_NOT_REACHED();
7379                 return NULL;
7380                 break;
7381         }
7382 }
7383
7384 static proto_item *
7385 proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
7386                                  tvbuff_t *tvb, const guint bit_offset,
7387                                  const gint no_of_bits, void *value_ptr,
7388                                  gchar *value_str)
7389 {
7390         proto_item *item;
7391
7392         if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
7393                                                       tvb, bit_offset, no_of_bits,
7394                                                       value_ptr, value_str))) {
7395                 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset));
7396                 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_SIZE(no_of_bits));
7397         }
7398         return item;
7399 }
7400
7401 #define CREATE_VALUE_STRING(dst,format,ap) \
7402         va_start(ap, format); \
7403         dst = ep_strdup_vprintf(format, ap); \
7404         va_end(ap);
7405
7406 proto_item *
7407 proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
7408                                       tvbuff_t *tvb, const guint bit_offset,
7409                                       const gint no_of_bits, guint32 value,
7410                                       const char *format, ...)
7411 {
7412         va_list ap;
7413         gchar  *dst;
7414         header_field_info *hf_field;
7415
7416         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
7417
7418         switch (hf_field->type) {
7419                 case FT_UINT8:
7420                 case FT_UINT16:
7421                 case FT_UINT24:
7422                 case FT_UINT32:
7423                         break;
7424
7425                 default:
7426                         DISSECTOR_ASSERT_NOT_REACHED();
7427                         return NULL;
7428                         break;
7429         }
7430
7431         CREATE_VALUE_STRING(dst, format, ap);
7432
7433         return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
7434 }
7435
7436 proto_item *
7437 proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
7438                                        tvbuff_t *tvb, const guint bit_offset,
7439                                        const gint no_of_bits, float value,
7440                                        const char *format, ...)
7441 {
7442         va_list ap;
7443         gchar  *dst;
7444         header_field_info *hf_field;
7445
7446         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
7447
7448         DISSECTOR_ASSERT(hf_field->type == FT_FLOAT);
7449
7450         CREATE_VALUE_STRING(dst, format, ap);
7451
7452         return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
7453 }
7454
7455 proto_item *
7456 proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
7457                                      tvbuff_t *tvb, const guint bit_offset,
7458                                      const gint no_of_bits, gint32 value,
7459                                      const char *format, ...)
7460 {
7461         va_list ap;
7462         gchar  *dst;
7463         header_field_info *hf_field;
7464
7465         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
7466
7467         switch (hf_field->type) {
7468                 case FT_INT8:
7469                 case FT_INT16:
7470                 case FT_INT24:
7471                 case FT_INT32:
7472                         break;
7473
7474                 default:
7475                         DISSECTOR_ASSERT_NOT_REACHED();
7476                         return NULL;
7477                         break;
7478         }
7479
7480         CREATE_VALUE_STRING(dst, format, ap);
7481
7482         return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
7483 }
7484
7485 proto_item *
7486 proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
7487                                          tvbuff_t *tvb, const guint bit_offset,
7488                                          const gint no_of_bits, guint32 value,
7489                                          const char *format, ...)
7490 {
7491         va_list ap;
7492         gchar  *dst;
7493         header_field_info *hf_field;
7494
7495         TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
7496
7497         DISSECTOR_ASSERT(hf_field->type == FT_BOOLEAN);
7498
7499         CREATE_VALUE_STRING(dst, format, ap);
7500
7501         return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, dst);
7502 }
7503
7504 guchar
7505 proto_check_field_name(const gchar *field_name)
7506 {
7507         return wrs_check_charset(fld_abbrev_chars, field_name);
7508 }
7509
7510 gboolean
7511 tree_expanded(int tree_type)
7512 {
7513         g_assert(tree_type >= 0 && tree_type < num_tree_types);
7514         return tree_is_expanded[tree_type >> 5] & (1 << (tree_type & 31));
7515 }
7516
7517 void
7518 tree_expanded_set(int tree_type, gboolean value)
7519 {
7520         g_assert(tree_type >= 0 && tree_type < num_tree_types);
7521
7522         if (value)
7523                 tree_is_expanded[tree_type >> 5] |= (1 << (tree_type & 31));
7524         else
7525                 tree_is_expanded[tree_type >> 5] &= ~(1 << (tree_type & 31));
7526 }
7527
7528 /*
7529  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
7530  *
7531  * Local variables:
7532  * c-basic-offset: 8
7533  * tab-width: 8
7534  * indent-tabs-mode: t
7535  * End:
7536  *
7537  * vi: set shiftwidth=8 tabstop=8 noexpandtab:
7538  * :indentSize=8:tabSize=8:noTabs=false:
7539  */