2 * Routines for protocol tree
6 * Ethereal - Network traffic analyzer
7 * By Gerald Combs <gerald@ethereal.com>
8 * Copyright 1998 Gerald Combs
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.
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.
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
35 #ifdef NEED_SNPRINTF_H
36 # include "snprintf.h"
41 #include "addr_resolv.h"
43 #include "ipv6-utils.h"
45 #include "epan_dissect.h"
49 #define cVALS(x) (const value_string*)(x)
52 proto_tree_free_node(proto_node *node, gpointer data);
54 static void fill_label_boolean(field_info *fi, gchar *label_str);
55 static void fill_label_uint(field_info *fi, gchar *label_str);
56 static void fill_label_uint64(field_info *fi, gchar *label_str);
57 static void fill_label_enumerated_uint(field_info *fi, gchar *label_str);
58 static void fill_label_enumerated_bitfield(field_info *fi, gchar *label_str);
59 static void fill_label_numeric_bitfield(field_info *fi, gchar *label_str);
60 static void fill_label_int(field_info *fi, gchar *label_str);
61 static void fill_label_int64(field_info *fi, gchar *label_str);
62 static void fill_label_enumerated_int(field_info *fi, gchar *label_str);
64 int hfinfo_bitwidth(header_field_info *hfinfo);
65 static char* hfinfo_uint_vals_format(header_field_info *hfinfo);
66 static char* hfinfo_uint_format(header_field_info *hfinfo);
67 static char* hfinfo_uint64_format(header_field_info *hfinfo);
68 static char* hfinfo_int_vals_format(header_field_info *hfinfo);
69 static char* hfinfo_int_format(header_field_info *hfinfo);
70 static char* hfinfo_int64_format(header_field_info *hfinfo);
73 proto_tree_add_node(proto_tree *tree, field_info *fi);
76 alloc_field_info(proto_tree *tree, int hfindex, tvbuff_t *tvb,
77 gint start, gint *length);
80 proto_tree_add_pi(proto_tree *tree, int hfindex, tvbuff_t *tvb,
81 gint start, gint *length, field_info **pfi);
84 proto_tree_set_representation(proto_item *pi, const char *format, va_list ap);
87 proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb);
89 proto_tree_set_bytes(field_info *fi, const guint8* start_ptr, gint length);
91 proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, gint offset, gint length);
93 proto_tree_set_time(field_info *fi, nstime_t *value_ptr);
95 proto_tree_set_string(field_info *fi, const char* value, gboolean);
97 proto_tree_set_string_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
99 proto_tree_set_ether(field_info *fi, const guint8* value);
101 proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, gint start);
103 proto_tree_set_ipxnet(field_info *fi, guint32 value);
105 proto_tree_set_ipv4(field_info *fi, guint32 value);
107 proto_tree_set_ipv6(field_info *fi, const guint8* value_ptr);
109 proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, gint start);
111 proto_tree_set_boolean(field_info *fi, guint32 value);
113 proto_tree_set_float(field_info *fi, float value);
115 proto_tree_set_double(field_info *fi, double value);
117 proto_tree_set_uint(field_info *fi, guint32 value);
119 proto_tree_set_int(field_info *fi, gint32 value);
121 proto_tree_set_uint64(field_info *fi, guint64 value);
123 proto_tree_set_uint64_tvb(field_info *fi, tvbuff_t *tvb, gint start, gboolean little_endian);
125 static int proto_register_field_init(header_field_info *hfinfo, int parent);
127 /* Comparision function for tree insertion. A wrapper around strcmp() */
128 static int g_strcmp(gconstpointer a, gconstpointer b);
130 /* special-case header field used within proto.c */
131 int hf_text_only = -1;
133 /* Structure for information about a protocol */
135 char *name; /* long description */
136 char *short_name; /* short description */
137 char *filter_name; /* name of this protocol in filters */
138 int proto_id; /* field ID for this protocol */
139 GList *fields; /* fields for this protocol */
140 GList *last_field; /* pointer to end of list of fields */
141 gboolean is_enabled; /* TRUE if protocol is enabled */
142 gboolean can_toggle; /* TRUE if is_enabled can be changed */
145 /* List of all protocols */
146 static GList *protocols = NULL;
148 #define INITIAL_NUM_PROTOCOL_HFINFO 200
151 /* Contains information about protocols and header fields. Used when
152 * dissectors register their data */
153 static GMemChunk *gmc_hfinfo = NULL;
155 /* Contains information about a field when a dissector calls
156 * proto_tree_add_item. */
157 SLAB_ITEM_TYPE_DEFINE(field_info)
158 static SLAB_FREE_LIST_DEFINE(field_info)
159 static field_info *field_info_tmp=NULL;
160 #define FIELD_INFO_NEW(fi) \
161 SLAB_ALLOC(fi, field_info)
162 #define FIELD_INFO_FREE(fi) \
163 SLAB_FREE(fi, field_info)
167 /* Contains the space for proto_nodes. */
168 SLAB_ITEM_TYPE_DEFINE(proto_node)
169 static SLAB_FREE_LIST_DEFINE(proto_node)
170 #define PROTO_NODE_NEW(node) \
171 SLAB_ALLOC(node, proto_node) \
172 node->first_child = NULL; \
173 node->last_child = NULL; \
176 #define PROTO_NODE_FREE(node) \
177 SLAB_FREE(node, proto_node)
181 /* String space for protocol and field items for the GUI */
182 SLAB_ITEM_TYPE_DEFINE(item_label_t)
183 static SLAB_FREE_LIST_DEFINE(item_label_t)
184 #define ITEM_LABEL_NEW(il) \
185 SLAB_ALLOC(il, item_label_t)
186 #define ITEM_LABEL_FREE(il) \
187 SLAB_FREE(il, item_label_t)
191 /* List which stores protocols and fields that have been registered */
192 typedef struct _gpa_hfinfo_t {
194 guint32 allocated_len;
195 header_field_info **hfi;
197 gpa_hfinfo_t gpa_hfinfo;
199 /* Balanced tree of abbreviations and IDs */
200 static GTree *gpa_name_tree = NULL;
202 /* Points to the first element of an array of Booleans, indexed by
203 a subtree item type; that array element is TRUE if subtrees of
204 an item of that type are to be expanded. */
205 gboolean *tree_is_expanded;
207 /* Number of elements in that array. */
210 /* Name hashtables for fast detection of duplicate names */
211 static GHashTable* proto_names = NULL;
212 static GHashTable* proto_short_names = NULL;
213 static GHashTable* proto_filter_names = NULL;
216 proto_compare_name(gconstpointer p1_arg, gconstpointer p2_arg)
218 const protocol_t *p1 = p1_arg;
219 const protocol_t *p2 = p2_arg;
221 return g_strcasecmp(p1->short_name, p2->short_name);
225 /* initialize data structures and register protocols and fields */
227 proto_init(const char *plugin_dir
232 void (register_all_protocols)(void),
233 void (register_all_protocol_handoffs)(void))
235 static hf_register_info hf[] = {
237 { "", "", FT_NONE, BASE_NONE, NULL, 0x0,
242 proto_names = g_hash_table_new(g_int_hash, g_int_equal);
243 proto_short_names = g_hash_table_new(g_int_hash, g_int_equal);
244 proto_filter_names = g_hash_table_new(g_int_hash, g_int_equal);
248 gmc_hfinfo = g_mem_chunk_new("gmc_hfinfo",
249 sizeof(header_field_info),
250 INITIAL_NUM_PROTOCOL_HFINFO * sizeof(header_field_info),
254 gpa_hfinfo.allocated_len=0;
256 gpa_name_tree = g_tree_new(g_strcmp);
258 /* Initialize the ftype subsystem */
261 /* Register one special-case FT_TEXT_ONLY field for use when
262 converting ethereal to new-style proto_tree. These fields
263 are merely strings on the GUI tree; they are not filterable */
264 proto_register_field_array(-1, hf, array_length(hf));
266 /* Have each built-in dissector register its protocols, fields,
267 dissector tables, and dissectors to be called through a
268 handle, and do whatever one-time initialization it needs to
270 register_all_protocols();
273 /* Now scan for plugins and load all the ones we find, calling
274 their register routines to do the stuff described above. */
275 init_plugins(plugin_dir);
278 /* Now call the "handoff registration" routines of all built-in
279 dissectors; those routines register the dissector in other
280 dissectors' handoff tables, and fetch any dissector handles
282 register_all_protocol_handoffs();
285 /* Now do the same with plugins. */
286 register_all_plugin_handoffs();
289 /* sort the protocols by protocol name */
290 protocols = g_list_sort(protocols, proto_compare_name);
292 /* We've assigned all the subtree type values; allocate the array
293 for them, and zero it out. */
294 tree_is_expanded = g_malloc(num_tree_types*sizeof (gint *));
295 memset(tree_is_expanded, 0, num_tree_types*sizeof (gint *));
298 /* String comparison func for dfilter_token GTree */
300 g_strcmp(gconstpointer a, gconstpointer b)
302 return strcmp((const char*)a, (const char*)b);
308 /* Free the abbrev/ID GTree */
310 g_tree_destroy(gpa_name_tree);
311 gpa_name_tree = NULL;
315 g_mem_chunk_destroy(gmc_hfinfo);
317 if(gpa_hfinfo.allocated_len){
319 gpa_hfinfo.allocated_len=0;
320 g_free(gpa_hfinfo.hfi);
323 if (tree_is_expanded != NULL)
324 g_free(tree_is_expanded);
328 typedef gboolean (*proto_tree_traverse_func)(proto_node *, gpointer);
331 proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
334 proto_node *pnode = tree;
338 if (func(pnode, data))
341 child = pnode->first_child;
342 while (child != NULL) {
344 * The routine we call might modify the child, e.g. by
345 * freeing it, so we get the child's successor before
346 * calling that routine.
349 child = current->next;
350 if (proto_tree_traverse_pre_order((proto_tree *)current, func,
359 proto_tree_traverse_in_order(proto_tree *tree, proto_tree_traverse_func func,
362 proto_node *pnode = tree;
366 child = pnode->first_child;
369 * The routine we call might modify the child, e.g. by
370 * freeing it, so we get the child's successor before
371 * calling that routine.
374 child = current->next;
376 if (proto_tree_traverse_in_order((proto_tree *)current, func,
380 if (func(pnode, data))
383 while (child != NULL) {
385 * The routine we call might modify the child, e.g. by
386 * freeing it, so we get the child's successor before
387 * calling that routine.
390 child = current->next;
391 if (proto_tree_traverse_in_order((proto_tree *)current,
396 if (func(pnode, data))
404 proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
407 proto_node *node = tree;
410 node = node->first_child;
411 while (node != NULL) {
413 node = current->next;
414 func((proto_tree *)current, data);
418 /* frees the resources that the dissection a proto_tree uses */
420 proto_tree_free(proto_tree *tree)
422 proto_tree_traverse_in_order(tree, proto_tree_free_node, NULL);
426 free_GPtrArray_value(gpointer key _U_, gpointer value, gpointer user_data _U_)
428 GPtrArray *ptrs = value;
430 g_ptr_array_free(ptrs, TRUE);
434 free_node_tree_data(tree_data_t *tree_data)
436 /* Free all the GPtrArray's in the interesting_hfids hash. */
437 g_hash_table_foreach(tree_data->interesting_hfids,
438 free_GPtrArray_value, NULL);
440 /* And then destroy the hash. */
441 g_hash_table_destroy(tree_data->interesting_hfids);
443 /* And finally the tree_data_t itself. */
447 #define FREE_NODE_FIELD_INFO(finfo) \
449 ITEM_LABEL_FREE(finfo->rep); \
451 FVALUE_CLEANUP(&finfo->value); \
452 FIELD_INFO_FREE(finfo);
455 proto_tree_free_node(proto_node *node, gpointer data _U_)
457 field_info *finfo = PITEM_FINFO(node);
460 /* This is the root node. Destroy the per-tree data.
461 * There is no field_info to destroy. */
462 free_node_tree_data(PTREE_DATA(node));
465 /* This is a child node. Don't free the per-tree data, but
466 * do free the field_info data. */
467 FREE_NODE_FIELD_INFO(finfo);
470 /* Free the proto_node. */
471 PROTO_NODE_FREE(node);
473 return FALSE; /* FALSE = do not end traversal of protocol tree */
476 /* Is the parsing being done for a visible proto_tree or an invisible one?
477 * By setting this correctly, the proto_tree creation is sped up by not
478 * having to call vsnprintf and copy strings around.
481 proto_tree_set_visible(proto_tree *tree, gboolean visible)
483 PTREE_DATA(tree)->visible = visible;
486 #define PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo) \
487 DISSECTOR_ASSERT((guint)hfindex < gpa_hfinfo.len); \
488 hfinfo=gpa_hfinfo.hfi[hfindex];
490 /* Finds a record in the hf_info_records array by id. */
492 proto_registrar_get_nth(guint hfindex)
494 register header_field_info *hfinfo;
496 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
500 /* Finds a record in the hf_info_records array by name.
503 proto_registrar_get_byname(const char *field_name)
505 DISSECTOR_ASSERT(field_name != NULL);
506 return g_tree_lookup(gpa_name_tree, (gpointer)field_name);
509 /* Add a text-only node, leaving it to our caller to fill the text in */
511 proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, gint start, gint length)
515 pi = proto_tree_add_pi(tree, hf_text_only, tvb, start, &length, NULL);
522 /* Add a text-only node to the proto_tree */
524 proto_tree_add_text(proto_tree *tree, tvbuff_t *tvb, gint start, gint length,
525 const char *format, ...)
530 pi = proto_tree_add_text_node(tree, tvb, start, length);
534 va_start(ap, format);
535 proto_tree_set_representation(pi, format, ap);
541 /* Add a text-only node to the proto_tree (va_list version) */
543 proto_tree_add_text_valist(proto_tree *tree, tvbuff_t *tvb, gint start,
544 gint length, const char *format, va_list ap)
548 pi = proto_tree_add_text_node(tree, tvb, start, length);
552 proto_tree_set_representation(pi, format, ap);
557 /* Add a text-only node for debugging purposes. The caller doesn't need
558 * to worry about tvbuff, start, or length. Debug message gets sent to
561 proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
566 pi = proto_tree_add_text_node(tree, NULL, 0, 0);
570 va_start(ap, format);
571 proto_tree_set_representation(pi, format, ap);
581 get_uint_value(tvbuff_t *tvb, gint offset, gint length, gboolean little_endian)
588 value = tvb_get_guint8(tvb, offset);
592 value = little_endian ? tvb_get_letohs(tvb, offset)
593 : tvb_get_ntohs(tvb, offset);
597 value = little_endian ? tvb_get_letoh24(tvb, offset)
598 : tvb_get_ntoh24(tvb, offset);
602 value = little_endian ? tvb_get_letohl(tvb, offset)
603 : tvb_get_ntohl(tvb, offset);
607 DISSECTOR_ASSERT_NOT_REACHED();
615 get_int_value(tvbuff_t *tvb, gint offset, gint length, gboolean little_endian)
622 value = (gint8)tvb_get_guint8(tvb, offset);
626 value = (gint16) (little_endian ? tvb_get_letohs(tvb, offset)
627 : tvb_get_ntohs(tvb, offset));
631 value = little_endian ? tvb_get_letoh24(tvb, offset)
632 : tvb_get_ntoh24(tvb, offset);
633 if (value & 0x00800000) {
634 /* Sign bit is set; sign-extend it. */
640 value = little_endian ? tvb_get_letohl(tvb, offset)
641 : tvb_get_ntohl(tvb, offset);
645 DISSECTOR_ASSERT_NOT_REACHED();
652 /* Add an item to a proto_tree, using the text label registered to that item;
653 the item is extracted from the tvbuff handed to it. */
655 proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
656 gint start, gint length, gboolean little_endian)
670 new_fi = alloc_field_info(tree, hfindex, tvb, start, &length);
675 /* there is a possibility here that we might raise an exception
676 * and thus would lose track of the field_info.
677 * store it in a temp so that if we come here again we can reclaim
678 * the field_info without leaking memory.
680 /* XXX this only keeps track of one field_info struct,
681 if we ever go multithreaded for calls to this function
682 we have to change this code to use per thread variable.
685 /* oops, last one we got must have been lost due
687 * good thing we saved it, now we can reverse the
688 * memory leak and reclaim it.
690 SLAB_FREE(field_info_tmp, field_info);
692 /* we might throw an exception, keep track of this one
693 * across the "dangerous" section below.
695 field_info_tmp=new_fi;
697 switch(new_fi->hfinfo->type) {
699 /* no value to set for FT_NONE */
703 proto_tree_set_protocol_tvb(new_fi, tvb);
707 proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
711 n = get_uint_value(tvb, start, length, little_endian);
712 proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
714 /* Instead of calling proto_item_set_len(), since we don't yet
715 * have a proto_item, we set the field_info's length ourselves. */
716 new_fi->length = n + length;
720 proto_tree_set_boolean(new_fi,
721 get_uint_value(tvb, start, length, little_endian));
724 /* XXX - make these just FT_UINT? */
729 proto_tree_set_uint(new_fi,
730 get_uint_value(tvb, start, length, little_endian));
735 DISSECTOR_ASSERT(length == 8);
736 proto_tree_set_uint64_tvb(new_fi, tvb, start, little_endian);
739 /* XXX - make these just FT_INT? */
744 proto_tree_set_int(new_fi,
745 get_int_value(tvb, start, length, little_endian));
749 DISSECTOR_ASSERT(length == 4);
750 tvb_memcpy(tvb, (guint8 *)&value, start, 4);
751 proto_tree_set_ipv4(new_fi, little_endian ? GUINT32_SWAP_LE_BE(value) : value);
755 DISSECTOR_ASSERT(length == 4);
756 proto_tree_set_ipxnet(new_fi,
757 get_uint_value(tvb, start, 4, FALSE));
761 DISSECTOR_ASSERT(length == 16);
762 proto_tree_set_ipv6_tvb(new_fi, tvb, start);
766 DISSECTOR_ASSERT(length == 6);
767 proto_tree_set_ether_tvb(new_fi, tvb, start);
771 DISSECTOR_ASSERT(length == 4);
773 floatval = tvb_get_letohieee_float(tvb, start);
775 floatval = tvb_get_ntohieee_float(tvb, start);
776 proto_tree_set_float(new_fi, floatval);
780 DISSECTOR_ASSERT(length == 8);
782 doubleval = tvb_get_letohieee_double(tvb, start);
784 doubleval = tvb_get_ntohieee_double(tvb, start);
785 proto_tree_set_double(new_fi, doubleval);
789 /* This g_strdup'ed memory is freed in proto_tree_free_node() */
790 proto_tree_set_string_tvb(new_fi, tvb, start, length);
794 if (length != 0) { /* XXX - Should we throw an exception instead? */
795 /* Instead of calling proto_item_set_len(),
796 * since we don't yet have a proto_item, we
797 * set the field_info's length ourselves.
799 * XXX - our caller can't use that length to
800 * advance an offset unless they arrange that
801 * there always be a protocol tree into which
802 * we're putting this item.
805 /* This can throw an exception */
806 length = tvb_strsize(tvb, start);
808 /* This g_malloc'ed memory is freed
809 in proto_tree_free_node() */
810 string = g_malloc(length);
812 tvb_memcpy(tvb, string, start, length);
813 new_fi->length = length;
816 /* In this case, length signifies
817 * the length of the string.
819 * This could either be a null-padded
820 * string, which doesn't necessarily
821 * have a '\0' at the end, or a
822 * null-terminated string, with a
823 * trailing '\0'. (Yes, there are
824 * cases where you have a string
825 * that's both counted and null-
828 * In the first case, we must
829 * allocate a buffer of length
830 * "length+1", to make room for
833 * In the second case, we don't
834 * assume that there is a trailing
835 * '\0' there, as the packet might
836 * be malformed. (XXX - should we
837 * throw an exception if there's no
838 * trailing '\0'?) Therefore, we
839 * allocate a buffer of length
840 * "length+1", and put in a trailing
841 * '\0', just to be safe.
843 * (XXX - this would change if
844 * we made string values counted
845 * rather than null-terminated.)
848 /* This g_malloc'ed memory is freed
849 * in proto_tree_free_node() */
850 string = tvb_get_string(tvb, start,
852 new_fi->length = length;
854 proto_tree_set_string(new_fi, string, TRUE);
859 /* This g_strdup'ed memory is freed in proto_tree_free_node() */
860 n = get_uint_value(tvb, start, length, little_endian);
861 proto_tree_set_string_tvb(new_fi, tvb, start + length, n);
863 /* Instead of calling proto_item_set_len(), since we
864 * don't yet have a proto_item, we set the
865 * field_info's length ourselves.
867 * XXX - our caller can't use that length to
868 * advance an offset unless they arrange that
869 * there always be a protocol tree into which
870 * we're putting this item.
872 new_fi->length = n + length;
876 g_error("new_fi->hfinfo->type %d (%s) not handled\n",
877 new_fi->hfinfo->type,
878 ftype_name(new_fi->hfinfo->type));
879 DISSECTOR_ASSERT_NOT_REACHED();
883 /* Don't add new node to proto_tree until now so that any exceptions
884 * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
885 pi = proto_tree_add_node(tree, new_fi);
887 /* we did not raise an exception so we dont have to remember this
888 * field_info struct any more.
892 /* If the proto_tree wants to keep a record of this finfo
893 * for quick lookup, then record it. */
894 hash = PTREE_DATA(tree)->interesting_hfids;
895 ptrs = g_hash_table_lookup(hash, GINT_TO_POINTER(hfindex));
897 g_ptr_array_add(ptrs, new_fi);
904 proto_tree_add_item_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb,
905 gint start, gint length, gboolean little_endian)
909 pi = proto_tree_add_item(tree, hfindex, tvb, start, length, little_endian);
913 PROTO_ITEM_SET_HIDDEN(pi);
919 /* Add a FT_NONE to a proto_tree */
921 proto_tree_add_none_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
922 gint length, const char *format, ...)
926 header_field_info *hfinfo;
931 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
932 DISSECTOR_ASSERT(hfinfo->type == FT_NONE);
934 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, NULL);
936 va_start(ap, format);
937 proto_tree_set_representation(pi, format, ap);
940 /* no value to set for FT_NONE */
946 proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb)
948 fvalue_set(&fi->value, tvb, TRUE);
951 /* Add a FT_PROTOCOL to a proto_tree */
953 proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
954 gint length, const char *format, ...)
958 header_field_info *hfinfo;
964 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
965 DISSECTOR_ASSERT(hfinfo->type == FT_PROTOCOL);
967 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
969 va_start(ap, format);
970 proto_tree_set_representation(pi, format, ap);
974 proto_tree_set_protocol_tvb(new_fi, tvb);
977 proto_tree_set_protocol_tvb(new_fi, NULL);
983 /* Add a FT_BYTES to a proto_tree */
985 proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
986 gint length, const guint8 *start_ptr)
990 header_field_info *hfinfo;
995 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
996 DISSECTOR_ASSERT(hfinfo->type == FT_BYTES);
998 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
999 proto_tree_set_bytes(new_fi, start_ptr, length);
1005 proto_tree_add_bytes_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
1006 gint length, const guint8 *start_ptr)
1010 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
1014 PROTO_ITEM_SET_HIDDEN(pi);
1020 proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
1021 gint length, const guint8 *start_ptr, const char *format, ...)
1026 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
1030 va_start(ap, format);
1031 proto_tree_set_representation(pi, format, ap);
1038 proto_tree_set_bytes(field_info *fi, const guint8* start_ptr, gint length)
1042 bytes = g_byte_array_new();
1044 g_byte_array_append(bytes, start_ptr, length);
1046 fvalue_set(&fi->value, bytes, TRUE);
1051 proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, gint offset, gint length)
1053 proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
1056 /* Add a FT_*TIME to a proto_tree */
1058 proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1059 nstime_t *value_ptr)
1063 header_field_info *hfinfo;
1068 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
1069 DISSECTOR_ASSERT(hfinfo->type == FT_ABSOLUTE_TIME ||
1070 hfinfo->type == FT_RELATIVE_TIME);
1072 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
1073 proto_tree_set_time(new_fi, value_ptr);
1079 proto_tree_add_time_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1080 nstime_t *value_ptr)
1084 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
1088 PROTO_ITEM_SET_HIDDEN(pi);
1094 proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1095 nstime_t *value_ptr, const char *format, ...)
1100 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
1104 va_start(ap, format);
1105 proto_tree_set_representation(pi, format, ap);
1111 /* Set the FT_*TIME value */
1113 proto_tree_set_time(field_info *fi, nstime_t *value_ptr)
1115 fvalue_set(&fi->value, value_ptr, FALSE);
1118 /* Add a FT_IPXNET to a proto_tree */
1120 proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1125 header_field_info *hfinfo;
1130 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
1131 DISSECTOR_ASSERT(hfinfo->type == FT_IPXNET);
1133 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
1134 proto_tree_set_ipxnet(new_fi, value);
1140 proto_tree_add_ipxnet_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1145 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
1149 PROTO_ITEM_SET_HIDDEN(pi);
1155 proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1156 guint32 value, const char *format, ...)
1161 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
1165 va_start(ap, format);
1166 proto_tree_set_representation(pi, format, ap);
1172 /* Set the FT_IPXNET value */
1174 proto_tree_set_ipxnet(field_info *fi, guint32 value)
1176 fvalue_set_integer(&fi->value, value);
1179 /* Add a FT_IPv4 to a proto_tree */
1181 proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1186 header_field_info *hfinfo;
1191 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
1192 DISSECTOR_ASSERT(hfinfo->type == FT_IPv4);
1194 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
1195 proto_tree_set_ipv4(new_fi, value);
1201 proto_tree_add_ipv4_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1206 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
1210 PROTO_ITEM_SET_HIDDEN(pi);
1216 proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1217 guint32 value, const char *format, ...)
1222 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
1226 va_start(ap, format);
1227 proto_tree_set_representation(pi, format, ap);
1233 /* Set the FT_IPv4 value */
1235 proto_tree_set_ipv4(field_info *fi, guint32 value)
1237 fvalue_set_integer(&fi->value, value);
1240 /* Add a FT_IPv6 to a proto_tree */
1242 proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1243 const guint8* value_ptr)
1247 header_field_info *hfinfo;
1252 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
1253 DISSECTOR_ASSERT(hfinfo->type == FT_IPv6);
1255 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
1256 proto_tree_set_ipv6(new_fi, value_ptr);
1262 proto_tree_add_ipv6_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1263 const guint8* value_ptr)
1267 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
1271 PROTO_ITEM_SET_HIDDEN(pi);
1277 proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1278 const guint8* value_ptr, const char *format, ...)
1283 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
1287 va_start(ap, format);
1288 proto_tree_set_representation(pi, format, ap);
1294 /* Set the FT_IPv6 value */
1296 proto_tree_set_ipv6(field_info *fi, const guint8* value_ptr)
1298 fvalue_set(&fi->value, (gpointer) value_ptr, FALSE);
1302 proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, gint start)
1304 proto_tree_set_ipv6(fi, tvb_get_ptr(tvb, start, 16));
1308 proto_tree_set_uint64(field_info *fi, guint64 value)
1310 fvalue_set_integer64(&fi->value, value);
1314 proto_tree_set_uint64_tvb(field_info *fi, tvbuff_t *tvb, gint start, gboolean little_endian)
1318 value = little_endian ? tvb_get_letoh64(tvb, start)
1319 : tvb_get_ntoh64(tvb, start);
1321 proto_tree_set_uint64(fi, value);
1324 /* Add a FT_STRING or FT_STRINGZ to a proto_tree. Creates own copy of string,
1325 * and frees it when the proto_tree is destroyed. */
1327 proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
1328 gint length, const char* value)
1332 header_field_info *hfinfo;
1337 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
1338 DISSECTOR_ASSERT(hfinfo->type == FT_STRING || hfinfo->type == FT_STRINGZ);
1340 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
1341 DISSECTOR_ASSERT(length >= 0);
1342 proto_tree_set_string(new_fi, value, FALSE);
1348 proto_tree_add_string_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
1349 gint length, const char* value)
1353 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
1357 PROTO_ITEM_SET_HIDDEN(pi);
1363 proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
1364 gint length, const char* value, const char *format, ...)
1369 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
1373 va_start(ap, format);
1374 proto_tree_set_representation(pi, format, ap);
1380 /* Appends string data to a FT_STRING or FT_STRINGZ, allowing progressive
1381 * field info update instead of only updating the representation as does
1382 * proto_item_append_text()
1385 proto_item_append_string(proto_item *pi, const char *str)
1388 header_field_info *hfinfo;
1389 gchar *old_str, *new_str;
1396 fi = PITEM_FINFO(pi);
1397 hfinfo = fi->hfinfo;
1398 DISSECTOR_ASSERT(hfinfo->type == FT_STRING || hfinfo->type == FT_STRINGZ);
1399 old_str = fvalue_get(&fi->value);
1400 new_str = g_malloc(strlen(old_str) + strlen(str) + 1);
1401 sprintf(new_str, "%s%s", old_str, str);
1402 fvalue_set(&fi->value, new_str, TRUE);
1405 /* Set the FT_STRING value */
1407 proto_tree_set_string(field_info *fi, const char* value,
1408 gboolean already_allocated)
1410 fvalue_set(&fi->value, (gpointer) value, already_allocated);
1414 proto_tree_set_string_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
1419 length = tvb_ensure_length_remaining(tvb, start);
1422 /* This memory is freed in proto_tree_free_node() */
1423 string = tvb_get_string(tvb, start, length);
1424 proto_tree_set_string(fi, string, TRUE);
1427 /* Add a FT_ETHER to a proto_tree */
1429 proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1430 const guint8* value)
1434 header_field_info *hfinfo;
1439 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
1440 DISSECTOR_ASSERT(hfinfo->type == FT_ETHER);
1442 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
1443 proto_tree_set_ether(new_fi, value);
1449 proto_tree_add_ether_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1450 const guint8* value)
1454 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
1458 PROTO_ITEM_SET_HIDDEN(pi);
1464 proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1465 const guint8* value, const char *format, ...)
1470 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
1474 va_start(ap, format);
1475 proto_tree_set_representation(pi, format, ap);
1481 /* Set the FT_ETHER value */
1483 proto_tree_set_ether(field_info *fi, const guint8* value)
1485 fvalue_set(&fi->value, (gpointer) value, FALSE);
1489 proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, gint start)
1491 proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, 6));
1494 /* Add a FT_BOOLEAN to a proto_tree */
1496 proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1501 header_field_info *hfinfo;
1506 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
1507 DISSECTOR_ASSERT(hfinfo->type == FT_BOOLEAN);
1509 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
1510 proto_tree_set_boolean(new_fi, value);
1516 proto_tree_add_boolean_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1521 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
1525 PROTO_ITEM_SET_HIDDEN(pi);
1531 proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1532 guint32 value, const char *format, ...)
1537 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
1541 va_start(ap, format);
1542 proto_tree_set_representation(pi, format, ap);
1548 /* Set the FT_BOOLEAN value */
1550 proto_tree_set_boolean(field_info *fi, guint32 value)
1552 proto_tree_set_uint(fi, value);
1555 /* Add a FT_FLOAT to a proto_tree */
1557 proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1562 header_field_info *hfinfo;
1567 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
1568 DISSECTOR_ASSERT(hfinfo->type == FT_FLOAT);
1570 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
1571 proto_tree_set_float(new_fi, value);
1577 proto_tree_add_float_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1582 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
1586 PROTO_ITEM_SET_HIDDEN(pi);
1592 proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1593 float value, const char *format, ...)
1598 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
1602 va_start(ap, format);
1603 proto_tree_set_representation(pi, format, ap);
1609 /* Set the FT_FLOAT value */
1611 proto_tree_set_float(field_info *fi, float value)
1613 fvalue_set_floating(&fi->value, value);
1616 /* Add a FT_DOUBLE to a proto_tree */
1618 proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1623 header_field_info *hfinfo;
1628 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
1629 DISSECTOR_ASSERT(hfinfo->type == FT_DOUBLE);
1631 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
1632 proto_tree_set_double(new_fi, value);
1638 proto_tree_add_double_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1643 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
1647 PROTO_ITEM_SET_HIDDEN(pi);
1653 proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1654 double value, const char *format, ...)
1659 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
1663 va_start(ap, format);
1664 proto_tree_set_representation(pi, format, ap);
1670 /* Set the FT_DOUBLE value */
1672 proto_tree_set_double(field_info *fi, double value)
1674 fvalue_set_floating(&fi->value, value);
1677 /* Add FT_UINT{8,16,24,32} to a proto_tree */
1679 proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1682 proto_item *pi = NULL;
1684 header_field_info *hfinfo;
1689 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
1690 switch(hfinfo->type) {
1696 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length,
1698 proto_tree_set_uint(new_fi, value);
1702 DISSECTOR_ASSERT_NOT_REACHED();
1709 proto_tree_add_uint_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1714 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
1718 PROTO_ITEM_SET_HIDDEN(pi);
1724 proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1725 guint32 value, const char *format, ...)
1730 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
1734 va_start(ap, format);
1735 proto_tree_set_representation(pi, format, ap);
1741 /* Set the FT_UINT{8,16,24,32} value */
1743 proto_tree_set_uint(field_info *fi, guint32 value)
1745 header_field_info *hfinfo;
1748 hfinfo = fi->hfinfo;
1751 if (hfinfo->bitmask) {
1752 /* Mask out irrelevant portions */
1753 integer &= hfinfo->bitmask;
1756 if (hfinfo->bitshift > 0) {
1757 integer >>= hfinfo->bitshift;
1760 fvalue_set_integer(&fi->value, integer);
1763 /* Add FT_UINT64 to a proto_tree */
1765 proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1768 proto_item *pi = NULL;
1770 header_field_info *hfinfo;
1775 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
1776 DISSECTOR_ASSERT(hfinfo->type == FT_UINT64);
1778 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
1779 proto_tree_set_uint64(new_fi, value);
1785 proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1786 guint64 value, const char *format, ...)
1791 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
1795 va_start(ap, format);
1796 proto_tree_set_representation(pi, format, ap);
1802 /* Add FT_INT{8,16,24,32} to a proto_tree */
1804 proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1807 proto_item *pi = NULL;
1809 header_field_info *hfinfo;
1814 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
1815 switch(hfinfo->type) {
1820 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length,
1822 proto_tree_set_int(new_fi, value);
1826 DISSECTOR_ASSERT_NOT_REACHED();
1833 proto_tree_add_int_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1838 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
1842 PROTO_ITEM_SET_HIDDEN(pi);
1848 proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1849 gint32 value, const char *format, ...)
1851 proto_item *pi = NULL;
1854 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
1858 va_start(ap, format);
1859 proto_tree_set_representation(pi, format, ap);
1865 /* Set the FT_INT{8,16,24,32} value */
1867 proto_tree_set_int(field_info *fi, gint32 value)
1869 header_field_info *hfinfo;
1872 hfinfo = fi->hfinfo;
1873 integer = (guint32) value;
1875 if (hfinfo->bitmask) {
1876 /* Mask out irrelevant portions */
1877 integer &= hfinfo->bitmask;
1880 if (hfinfo->bitshift > 0) {
1881 integer >>= hfinfo->bitshift;
1884 fvalue_set_integer(&fi->value, integer);
1887 /* Add FT_INT64 to a proto_tree */
1889 proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1892 proto_item *pi = NULL;
1894 header_field_info *hfinfo;
1899 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
1900 DISSECTOR_ASSERT(hfinfo->type == FT_INT64);
1902 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
1903 proto_tree_set_uint64(new_fi, (guint64)value);
1909 proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1910 gint64 value, const char *format, ...)
1915 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
1919 va_start(ap, format);
1920 proto_tree_set_representation(pi, format, ap);
1927 /* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
1929 proto_tree_add_node(proto_tree *tree, field_info *fi)
1931 proto_node *pnode, *tnode, *sibling;
1935 * Make sure "tree" is ready to have subtrees under it, by
1936 * checking whether it's been given an ett_ value.
1938 * "tnode->finfo" may be null; that's the case for the root
1939 * node of the protocol tree. That node is not displayed,
1940 * so it doesn't need an ett_ value to remember whether it
1945 if (tfi != NULL && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
1946 REPORT_DISSECTOR_BUG(g_strdup_printf("\"%s\" - \"%s\" tfi->tree_type: %u invalid (%s:%u)",
1947 fi->hfinfo->name, fi->hfinfo->abbrev, tfi->tree_type, __FILE__, __LINE__));
1948 /* XXX - is it safe to continue here? */
1951 DISSECTOR_ASSERT(tfi == NULL ||
1952 (tfi->tree_type >= 0 && tfi->tree_type < num_tree_types));
1954 PROTO_NODE_NEW(pnode);
1955 pnode->parent = tnode;
1957 pnode->tree_data = PTREE_DATA(tree);
1959 if (tnode->last_child != NULL) {
1960 sibling = tnode->last_child;
1961 DISSECTOR_ASSERT(sibling->next == NULL);
1962 sibling->next = pnode;
1964 tnode->first_child = pnode;
1965 tnode->last_child = pnode;
1967 return (proto_item*)pnode;
1971 /* Generic way to allocate field_info and add to proto_tree.
1972 * Sets *pfi to address of newly-allocated field_info struct, if pfi is
1975 proto_tree_add_pi(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
1976 gint *length, field_info **pfi)
1986 fi = alloc_field_info(tree, hfindex, tvb, start, length);
1987 pi = proto_tree_add_node(tree, fi);
1989 /* If the proto_tree wants to keep a record of this finfo
1990 * for quick lookup, then record it. */
1991 hash = PTREE_DATA(tree)->interesting_hfids;
1992 ptrs = g_hash_table_lookup(hash, GINT_TO_POINTER(hfindex));
1994 g_ptr_array_add(ptrs, fi);
1997 /* Does the caller want to know the fi pointer? */
2006 alloc_field_info(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
2009 header_field_info *hfinfo;
2012 gint length_remaining;
2015 * We only allow a null tvbuff if the item has a zero length,
2016 * i.e. if there's no data backing it.
2018 DISSECTOR_ASSERT(tvb != NULL || *length == 0);
2020 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
2023 * XXX - in some protocols, there are 32-bit unsigned length
2024 * fields, so lengths in protocol tree and tvbuff routines
2025 * should really be unsigned. We should have, for those
2026 * field types for which "to the end of the tvbuff" makes sense,
2027 * additional routines that take no length argument and
2028 * add fields that run to the end of the tvbuff.
2030 if (*length == -1) {
2032 * For FT_NONE, FT_PROTOCOL, FT_BYTES, and FT_STRING fields,
2033 * a length of -1 means "set the length to what remains in
2036 * The assumption is either that
2038 * 1) the length of the item can only be determined
2039 * by dissection (typically true of items with
2040 * subitems, which are probably FT_NONE or
2045 * 2) if the tvbuff is "short" (either due to a short
2046 * snapshot length or due to lack of reassembly of
2047 * fragments/segments/whatever), we want to display
2048 * what's available in the field (probably FT_BYTES
2049 * or FT_STRING) and then throw an exception later
2053 * 3) the field is defined to be "what's left in the
2056 * so we set the length to what remains in the tvbuff so
2057 * that, if we throw an exception while dissecting, it
2058 * has what is probably the right value.
2060 * For FT_STRINGZ, it means "the string is null-terminated,
2061 * not null-padded; set the length to the actual length
2062 * of the string", and if the tvbuff if short, we just
2063 * throw an exception.
2065 * It's not valid for any other type of field.
2067 switch (hfinfo->type) {
2071 * We allow this to be zero-length - for
2072 * example, an ONC RPC NULL procedure has
2073 * neither arguments nor reply, so the
2074 * payload for that protocol is empty.
2076 * However, if the length is negative, the
2077 * start offset is *past* the byte past the
2078 * end of the tvbuff, so we throw an
2081 *length = tvb_length_remaining(tvb, start);
2084 * Use "tvb_ensure_bytes_exist()"
2085 * to force the appropriate exception
2088 tvb_ensure_bytes_exist(tvb, start, 0);
2090 DISSECTOR_ASSERT(*length >= 0);
2096 *length = tvb_ensure_length_remaining(tvb, start);
2097 DISSECTOR_ASSERT(*length >= 0);
2102 * Leave the length as -1, so our caller knows
2108 DISSECTOR_ASSERT_NOT_REACHED();
2110 item_length = *length;
2112 item_length = *length;
2113 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
2115 * These types are for interior nodes of the
2116 * tree, and don't have data associated with
2117 * them; if the length is negative (XXX - see
2118 * above) or goes past the end of the tvbuff,
2119 * cut it short at the end of the tvbuff.
2120 * That way, if this field is selected in
2121 * Ethereal, we don't highlight stuff past
2122 * the end of the data.
2124 /* XXX - what to do, if we don't have a tvb? */
2126 length_remaining = tvb_length_remaining(tvb, start);
2127 if (item_length < 0 || (item_length > 0 && (length_remaining < item_length)))
2128 item_length = length_remaining;
2131 if (item_length < 0) {
2132 REPORT_DISSECTOR_BUG(g_strdup_printf("\"%s\" - \"%s\" invalid length: %d (%s:%u)",
2133 hfinfo->name, hfinfo->abbrev, item_length,
2134 __FILE__, __LINE__));
2140 fi->hfinfo = hfinfo;
2142 fi->start+=(tvb)?TVB_RAW_OFFSET(tvb):0;
2143 fi->length = item_length;
2146 if (!PTREE_DATA(tree)->visible)
2147 FI_SET_FLAG(fi, FI_HIDDEN);
2148 fvalue_init(&fi->value, fi->hfinfo->type);
2151 /* add the data source tvbuff */
2152 fi->ds_tvb=tvb?TVB_GET_DS_TVB(tvb):NULL;
2157 /* Set representation of a proto_tree entry, if the protocol tree is to
2160 proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
2162 int ret; /*tmp return value */
2163 field_info *fi = PITEM_FINFO(pi);
2165 if (!PROTO_ITEM_IS_HIDDEN(pi)) {
2166 ITEM_LABEL_NEW(fi->rep);
2167 ret = vsnprintf(fi->rep->representation, ITEM_LABEL_LENGTH, format, ap);
2168 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
2169 fi->rep->representation[ITEM_LABEL_LENGTH - 1] = '\0';
2173 /* Set text of proto_item after having already been created. */
2175 proto_item_set_text(proto_item *pi, const char *format, ...)
2177 field_info *fi = NULL;
2184 fi = PITEM_FINFO(pi);
2187 ITEM_LABEL_FREE(fi->rep);
2190 va_start(ap, format);
2191 proto_tree_set_representation(pi, format, ap);
2195 /* Append to text of proto_item after having already been created. */
2197 proto_item_append_text(proto_item *pi, const char *format, ...)
2199 field_info *fi = NULL;
2202 int ret; /*tmp return value */
2208 fi = PITEM_FINFO(pi);
2210 if (!PROTO_ITEM_IS_HIDDEN(pi)) {
2211 va_start(ap, format);
2214 * If we don't already have a representation,
2215 * generate the default representation.
2217 if (fi->rep == NULL) {
2218 ITEM_LABEL_NEW(fi->rep);
2219 proto_item_fill_label(fi, fi->rep->representation);
2222 curlen = strlen(fi->rep->representation);
2223 if (ITEM_LABEL_LENGTH > curlen) {
2224 ret = vsnprintf(fi->rep->representation + curlen,
2225 ITEM_LABEL_LENGTH - curlen, format, ap);
2226 if ((ret == -1) || (ret >= (int)(ITEM_LABEL_LENGTH - curlen)))
2227 fi->rep->representation[ITEM_LABEL_LENGTH - 1] = '\0';
2234 proto_item_set_len(proto_item *pi, gint length)
2240 fi = PITEM_FINFO(pi);
2241 DISSECTOR_ASSERT(length >= 0);
2242 fi->length = length;
2246 * Sets the length of the item based on its start and on the specified
2247 * offset, which is the offset past the end of the item; as the start
2248 * in the item is relative to the beginning of the data source tvbuff,
2249 * we need to pass in a tvbuff - the end offset is relative to the beginning
2253 proto_item_set_end(proto_item *pi, tvbuff_t *tvb, gint end)
2259 fi = PITEM_FINFO(pi);
2260 end += TVB_RAW_OFFSET(tvb);
2261 DISSECTOR_ASSERT(end >= fi->start);
2262 fi->length = end - fi->start;
2266 proto_item_get_len(proto_item *pi)
2268 field_info *fi = PITEM_FINFO(pi);
2273 proto_tree_create_root(void)
2277 /* Initialize the proto_node */
2278 PROTO_NODE_NEW(pnode);
2279 pnode->parent = NULL;
2280 pnode->finfo = NULL;
2281 pnode->tree_data = g_new(tree_data_t, 1);
2283 /* Initialize the tree_data_t */
2284 pnode->tree_data->interesting_hfids =
2285 g_hash_table_new(g_direct_hash, g_direct_equal);
2287 /* Set the default to FALSE so it's easier to
2288 * find errors; if we expect to see the protocol tree
2289 * but for some reason the default 'visible' is not
2290 * changed, then we'll find out very quickly. */
2291 pnode->tree_data->visible = FALSE;
2293 return (proto_tree*) pnode;
2297 /* "prime" a proto_tree with a single hfid that a dfilter
2298 * is interested in. */
2300 proto_tree_prime_hfid(proto_tree *tree, gint hfid)
2302 g_hash_table_insert(PTREE_DATA(tree)->interesting_hfids,
2303 GINT_TO_POINTER(hfid), g_ptr_array_new());
2308 proto_item_add_subtree(proto_item *pi, gint idx) {
2314 fi = PITEM_FINFO(pi);
2315 DISSECTOR_ASSERT(idx >= 0 && idx < num_tree_types);
2316 fi->tree_type = idx;
2317 return (proto_tree*) pi;
2321 proto_item_get_subtree(proto_item *pi) {
2326 fi = PITEM_FINFO(pi);
2327 if (fi->tree_type == -1)
2329 return (proto_tree*) pi;
2333 proto_item_get_parent(proto_item *ti) {
2340 proto_item_get_parent_nth(proto_item *ti, int gen) {
2353 proto_tree_get_parent(proto_tree *tree) {
2356 return (proto_item*) tree;
2361 proto_register_protocol(char *name, char *short_name, char *filter_name)
2363 protocol_t *protocol;
2364 header_field_info *hfinfo;
2366 char *existing_name;
2369 gboolean found_invalid;
2372 * Make sure there's not already a protocol with any of those
2373 * names. Crash if there is, as that's an error in the code
2374 * or an inappropriate plugin.
2375 * This situation has to be fixed to not register more than one
2376 * protocol with the same name.
2378 * This is done by reducing the number of strcmp (and alike) calls as much as possible,
2379 * as this significally slows down startup time.
2381 * Drawback: As a hash value is used to reduce insert time,
2382 * this might lead to a hash collision.
2383 * However, as we have around 500+ protocols and we're using a 32 bit int this is very,
2387 key = g_malloc (sizeof(gint));
2388 *key = g_str_hash(name);
2389 existing_name = g_hash_table_lookup(proto_names, key);
2390 if (existing_name != NULL) {
2391 /* g_error will terminate the program */
2392 g_error("Duplicate protocol name \"%s\"!"
2393 " This might be caused by an inappropriate plugin or a development error.", name);
2395 g_hash_table_insert(proto_names, key, name);
2397 key = g_malloc (sizeof(gint));
2398 *key = g_str_hash(short_name);
2399 existing_name = g_hash_table_lookup(proto_short_names, key);
2400 if (existing_name != NULL) {
2401 g_error("Duplicate protocol short_name \"%s\"!"
2402 " This might be caused by an inappropriate plugin or a development error.", short_name);
2404 g_hash_table_insert(proto_short_names, key, short_name);
2406 found_invalid = FALSE;
2407 for (i = 0; i < strlen(filter_name); i++) {
2408 if (! (islower(filter_name[i]) ||
2409 isdigit(filter_name[i]) ||
2410 filter_name[i] == '-' ||
2411 filter_name[i] == '_' ||
2412 filter_name[i] == '.' )) {
2413 found_invalid = TRUE;
2416 if (found_invalid) {
2417 g_warning("Protocol filter name \"%s\" has one or more invalid characters.", filter_name);
2419 key = g_malloc (sizeof(gint));
2420 *key = g_str_hash(filter_name);
2421 existing_name = g_hash_table_lookup(proto_filter_names, key);
2422 if (existing_name != NULL) {
2423 g_error("Duplicate protocol filter_name \"%s\"!"
2424 " This might be caused by an inappropriate plugin or a development error.", filter_name);
2426 g_hash_table_insert(proto_filter_names, key, filter_name);
2428 /* Add this protocol to the list of known protocols; the list
2429 is sorted by protocol short name. */
2430 protocol = g_malloc(sizeof (protocol_t));
2431 protocol->name = name;
2432 protocol->short_name = short_name;
2433 protocol->filter_name = filter_name;
2434 protocol->fields = NULL;
2435 protocol->is_enabled = TRUE; /* protocol is enabled by default */
2436 protocol->can_toggle = TRUE;
2437 /* list will be sorted later by name, when all protocols completed registering */
2438 protocols = g_list_append(protocols, protocol);
2440 /* Here we do allocate a new header_field_info struct */
2441 hfinfo = g_mem_chunk_alloc(gmc_hfinfo);
2442 hfinfo->name = name;
2443 hfinfo->abbrev = filter_name;
2444 hfinfo->type = FT_PROTOCOL;
2445 hfinfo->strings = protocol;
2446 hfinfo->bitmask = 0;
2447 hfinfo->bitshift = 0;
2449 hfinfo->parent = -1; /* this field differentiates protos and fields */
2451 proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
2452 protocol->proto_id = proto_id;
2457 * Routines to use to iterate over the protocols.
2458 * The argument passed to the iterator routines is an opaque cookie to
2459 * their callers; it's the GList pointer for the current element in
2461 * The ID of the protocol is returned, or -1 if there is no protocol.
2464 proto_get_first_protocol(void **cookie)
2466 protocol_t *protocol;
2468 if (protocols == NULL)
2470 *cookie = protocols;
2471 protocol = protocols->data;
2472 return protocol->proto_id;
2476 proto_get_next_protocol(void **cookie)
2478 GList *list_item = *cookie;
2479 protocol_t *protocol;
2481 list_item = g_list_next(list_item);
2482 if (list_item == NULL)
2484 *cookie = list_item;
2485 protocol = list_item->data;
2486 return protocol->proto_id;
2490 proto_get_first_protocol_field(int proto_id, void **cookie)
2492 protocol_t *protocol = find_protocol_by_id(proto_id);
2493 hf_register_info *ptr;
2495 if ((protocol == NULL) || (protocol->fields == NULL))
2498 *cookie = protocol->fields;
2499 ptr = protocol->fields->data;
2500 return &ptr->hfinfo;
2504 proto_get_next_protocol_field(void **cookie)
2506 GList *list_item = *cookie;
2507 hf_register_info *ptr;
2509 list_item = g_list_next(list_item);
2510 if (list_item == NULL)
2513 *cookie = list_item;
2514 ptr = list_item->data;
2515 return &ptr->hfinfo;
2519 find_protocol_by_id(int proto_id)
2521 header_field_info *hfinfo;
2526 PROTO_REGISTRAR_GET_NTH(proto_id, hfinfo);
2527 DISSECTOR_ASSERT(hfinfo->type==FT_PROTOCOL);
2528 return (protocol_t *)hfinfo->strings;
2531 static gint compare_filter_name(gconstpointer proto_arg,
2532 gconstpointer filter_name)
2534 const protocol_t *protocol = proto_arg;
2535 const gchar* f_name = filter_name;
2537 return (strcmp(protocol->filter_name, f_name));
2541 proto_get_id(protocol_t *protocol)
2543 return protocol->proto_id;
2546 int proto_get_id_by_filter_name(gchar* filter_name)
2549 protocol_t *protocol;
2551 list_entry = g_list_find_custom(protocols, filter_name,
2552 compare_filter_name);
2553 if (list_entry == NULL)
2555 protocol = list_entry->data;
2556 return protocol->proto_id;
2560 proto_get_protocol_name(int proto_id)
2562 protocol_t *protocol;
2564 protocol = find_protocol_by_id(proto_id);
2565 return protocol->name;
2569 proto_get_protocol_short_name(protocol_t *protocol)
2571 if (protocol == NULL)
2573 return protocol->short_name;
2577 proto_get_protocol_filter_name(int proto_id)
2579 protocol_t *protocol;
2581 protocol = find_protocol_by_id(proto_id);
2582 return protocol->filter_name;
2586 proto_is_protocol_enabled(protocol_t *protocol)
2588 return protocol->is_enabled;
2592 proto_can_toggle_protocol(int proto_id)
2594 protocol_t *protocol;
2596 protocol = find_protocol_by_id(proto_id);
2597 return protocol->can_toggle;
2601 proto_set_decoding(int proto_id, gboolean enabled)
2603 protocol_t *protocol;
2605 protocol = find_protocol_by_id(proto_id);
2606 DISSECTOR_ASSERT(protocol->can_toggle);
2607 protocol->is_enabled = enabled;
2611 proto_set_cant_toggle(int proto_id)
2613 protocol_t *protocol;
2615 protocol = find_protocol_by_id(proto_id);
2616 protocol->can_toggle = FALSE;
2619 /* for use with static arrays only, since we don't allocate our own copies
2620 of the header_field_info struct contained within the hf_register_info struct */
2622 proto_register_field_array(int parent, hf_register_info *hf, int num_records)
2625 hf_register_info *ptr = hf;
2628 proto = find_protocol_by_id(parent);
2629 for (i = 0; i < num_records; i++, ptr++) {
2631 * Make sure we haven't registered this yet.
2632 * Most fields have variables associated with them
2633 * that are initialized to -1; some have array elements,
2634 * or possibly uninitialized variables, so we also allow
2635 * 0 (which is unlikely to be the field ID we get back
2636 * from "proto_register_field_init()").
2638 DISSECTOR_ASSERT(*ptr->p_id == -1 || *ptr->p_id == 0);
2640 if (proto != NULL) {
2641 if (proto->fields == NULL) {
2642 proto->fields = g_list_append(NULL, ptr);
2643 proto->last_field = proto->fields;
2646 g_list_append(proto->last_field, ptr)->next;
2649 field_id = proto_register_field_init(&ptr->hfinfo, parent);
2650 *ptr->p_id = field_id;
2655 proto_register_field_init(header_field_info *hfinfo, int parent)
2657 /* The field must have names */
2658 DISSECTOR_ASSERT(hfinfo->name);
2659 DISSECTOR_ASSERT(hfinfo->abbrev);
2661 /* These types of fields are allowed to have value_strings, true_false_strings or a protocol_t struct*/
2662 DISSECTOR_ASSERT((hfinfo->strings == NULL) || (
2663 (hfinfo->type == FT_UINT8) ||
2664 (hfinfo->type == FT_UINT16) ||
2665 (hfinfo->type == FT_UINT24) ||
2666 (hfinfo->type == FT_UINT32) ||
2667 (hfinfo->type == FT_INT8) ||
2668 (hfinfo->type == FT_INT16) ||
2669 (hfinfo->type == FT_INT24) ||
2670 (hfinfo->type == FT_INT32) ||
2671 (hfinfo->type == FT_BOOLEAN) ||
2672 (hfinfo->type == FT_PROTOCOL) ||
2673 (hfinfo->type == FT_FRAMENUM) ));
2675 switch (hfinfo->type) {
2685 /* Require integral types (other than frame number, which is
2686 always displayed in decimal) to have a number base */
2687 DISSECTOR_ASSERT(hfinfo->display != BASE_NONE);
2691 /* Don't allow bitfields or value strings for frame numbers */
2692 DISSECTOR_ASSERT(hfinfo->bitmask == 0);
2693 DISSECTOR_ASSERT(hfinfo->strings == NULL);
2699 /* if this is a bitfield, compute bitshift */
2700 if (hfinfo->bitmask) {
2701 while ((hfinfo->bitmask & (1 << hfinfo->bitshift)) == 0)
2705 hfinfo->parent = parent;
2706 hfinfo->same_name_next = NULL;
2707 hfinfo->same_name_prev = NULL;
2709 /* if we always add and never delete, then id == len - 1 is correct */
2710 if(gpa_hfinfo.len>=gpa_hfinfo.allocated_len){
2711 if(!gpa_hfinfo.hfi){
2712 gpa_hfinfo.allocated_len=1000;
2713 gpa_hfinfo.hfi=g_malloc(sizeof(header_field_info *)*1000);
2715 gpa_hfinfo.allocated_len+=1000;
2716 gpa_hfinfo.hfi=g_realloc(gpa_hfinfo.hfi, sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
2719 gpa_hfinfo.hfi[gpa_hfinfo.len]=hfinfo;
2721 hfinfo->id = gpa_hfinfo.len - 1;
2723 /* if we have real names, enter this field in the name tree */
2724 if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) {
2726 header_field_info *same_name_hfinfo, *same_name_next_hfinfo;
2730 /* Check that the filter name (abbreviation) is legal;
2731 * it must contain only alphanumerics, '-', "_", and ".". */
2732 for (p = hfinfo->abbrev; (c = *p) != '\0'; p++)
2733 DISSECTOR_ASSERT(isalnum(c) || c == '-' || c == '_' ||
2736 /* We allow multiple hfinfo's to be registered under the same
2737 * abbreviation. This was done for X.25, as, depending
2738 * on whether it's modulo-8 or modulo-128 operation,
2739 * some bitfield fields may be in different bits of
2740 * a byte, and we want to be able to refer to that field
2741 * with one name regardless of whether the packets
2742 * are modulo-8 or modulo-128 packets. */
2743 same_name_hfinfo = g_tree_lookup(gpa_name_tree, hfinfo->abbrev);
2744 if (same_name_hfinfo) {
2745 /* There's already a field with this name.
2746 * Put it after that field in the list of
2747 * fields with this name, then allow the code
2748 * after this if{} block to replace the old
2749 * hfinfo with the new hfinfo in the GTree. Thus,
2750 * we end up with a linked-list of same-named hfinfo's,
2751 * with the root of the list being the hfinfo in the GTree */
2752 same_name_next_hfinfo =
2753 same_name_hfinfo->same_name_next;
2755 hfinfo->same_name_next = same_name_next_hfinfo;
2756 if (same_name_next_hfinfo)
2757 same_name_next_hfinfo->same_name_prev = hfinfo;
2759 same_name_hfinfo->same_name_next = hfinfo;
2760 hfinfo->same_name_prev = same_name_hfinfo;
2762 g_tree_insert(gpa_name_tree, hfinfo->abbrev, hfinfo);
2769 proto_register_subtree_array(gint *const *indices, int num_indices)
2772 gint *const *ptr = indices;
2775 * If we've already allocated the array of tree types, expand
2776 * it; this lets plugins such as mate add tree types after
2777 * the initial startup. (If we haven't already allocated it,
2778 * we don't allocate it; on the first pass, we just assign
2779 * ett values and keep track of how many we've assigned, and
2780 * when we're finished registering all dissectors we allocate
2781 * the array, so that we do only one allocation rather than
2782 * wasting CPU time and memory by growing the array for each
2783 * dissector that registers ett values.)
2785 if (tree_is_expanded != NULL) {
2787 g_realloc(tree_is_expanded,
2788 (num_tree_types+num_indices)*sizeof (gint *));
2789 memset(tree_is_expanded + num_tree_types, 0,
2790 num_indices*sizeof (gint *));
2794 * Assign "num_indices" subtree numbers starting at "num_tree_types",
2795 * returning the indices through the pointers in the array whose
2796 * first element is pointed to by "indices", and update
2797 * "num_tree_types" appropriately.
2799 for (i = 0; i < num_indices; i++, ptr++, num_tree_types++)
2800 **ptr = num_tree_types;
2804 proto_item_fill_label(field_info *fi, gchar *label_str)
2806 header_field_info *hfinfo = fi->hfinfo;
2811 guint32 n_addr; /* network-order IPv4 address */
2812 int ret; /*tmp return value */
2814 switch(hfinfo->type) {
2817 ret = snprintf(label_str, ITEM_LABEL_LENGTH,
2818 "%s", hfinfo->name);
2819 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
2820 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
2824 fill_label_boolean(fi, label_str);
2829 bytes = fvalue_get(&fi->value);
2831 ret = snprintf(label_str, ITEM_LABEL_LENGTH,
2832 "%s: %s", hfinfo->name,
2833 bytes_to_str(bytes, fvalue_length(&fi->value)));
2834 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
2835 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
2838 ret = snprintf(label_str, ITEM_LABEL_LENGTH,
2839 "%s: <MISSING>", hfinfo->name);
2840 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
2841 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
2845 /* Four types of integers to take care of:
2846 * Bitfield, with val_string
2847 * Bitfield, w/o val_string
2848 * Non-bitfield, with val_string
2849 * Non-bitfield, w/o val_string
2856 if (hfinfo->bitmask) {
2857 if (hfinfo->strings) {
2858 fill_label_enumerated_bitfield(fi, label_str);
2861 fill_label_numeric_bitfield(fi, label_str);
2865 if (hfinfo->strings) {
2866 fill_label_enumerated_uint(fi, label_str);
2869 fill_label_uint(fi, label_str);
2875 fill_label_uint64(fi, label_str);
2882 DISSECTOR_ASSERT(!hfinfo->bitmask);
2883 if (hfinfo->strings) {
2884 fill_label_enumerated_int(fi, label_str);
2887 fill_label_int(fi, label_str);
2892 fill_label_int64(fi, label_str);
2896 ret = snprintf(label_str, ITEM_LABEL_LENGTH,
2897 "%s: %." STRINGIFY(FLT_DIG) "f",
2898 hfinfo->name, fvalue_get_floating(&fi->value));
2899 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
2900 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
2904 ret = snprintf(label_str, ITEM_LABEL_LENGTH,
2905 "%s: %." STRINGIFY(DBL_DIG) "g",
2906 hfinfo->name, fvalue_get_floating(&fi->value));
2907 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
2908 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
2911 case FT_ABSOLUTE_TIME:
2912 ret = snprintf(label_str, ITEM_LABEL_LENGTH,
2913 "%s: %s", hfinfo->name,
2914 abs_time_to_str(fvalue_get(&fi->value)));
2915 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
2916 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
2919 case FT_RELATIVE_TIME:
2920 ret = snprintf(label_str, ITEM_LABEL_LENGTH,
2921 "%s: %s seconds", hfinfo->name,
2922 rel_time_to_secs_str(fvalue_get(&fi->value)));
2923 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
2924 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
2928 integer = fvalue_get_integer(&fi->value);
2929 ret = snprintf(label_str, ITEM_LABEL_LENGTH,
2930 "%s: 0x%08X (%s)", hfinfo->name,
2931 integer, get_ipxnet_name(integer));
2932 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
2933 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
2937 bytes = fvalue_get(&fi->value);
2938 ret = snprintf(label_str, ITEM_LABEL_LENGTH,
2939 "%s: %s (%s)", hfinfo->name,
2940 ether_to_str(bytes),
2941 get_ether_name(bytes));
2942 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
2943 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
2947 ipv4 = fvalue_get(&fi->value);
2948 n_addr = ipv4_get_net_order_addr(ipv4);
2949 ret = snprintf(label_str, ITEM_LABEL_LENGTH,
2950 "%s: %s (%s)", hfinfo->name,
2951 get_hostname(n_addr),
2952 ip_to_str((guint8*)&n_addr));
2953 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
2954 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
2958 bytes = fvalue_get(&fi->value);
2959 ret = snprintf(label_str, ITEM_LABEL_LENGTH,
2960 "%s: %s (%s)", hfinfo->name,
2961 get_hostname6((struct e_in6_addr *)bytes),
2962 ip6_to_str((struct e_in6_addr*)bytes));
2963 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
2964 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
2969 case FT_UINT_STRING:
2970 bytes = fvalue_get(&fi->value);
2971 ret = snprintf(label_str, ITEM_LABEL_LENGTH,
2972 "%s: %s", hfinfo->name,
2973 format_text(bytes, strlen(bytes)));
2974 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
2975 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
2979 g_error("hfinfo->type %d (%s) not handled\n",
2981 ftype_name(hfinfo->type));
2982 DISSECTOR_ASSERT_NOT_REACHED();
2988 fill_label_boolean(field_info *fi, gchar *label_str)
2990 char *p = label_str;
2991 int bitfield_byte_length = 0, bitwidth;
2992 guint32 unshifted_value;
2994 int ret; /*tmp return value */
2996 header_field_info *hfinfo = fi->hfinfo;
2997 static const true_false_string default_tf = { "True", "False" };
2998 const true_false_string *tfstring = &default_tf;
3000 if (hfinfo->strings) {
3001 tfstring = (const struct true_false_string*) hfinfo->strings;
3004 value = fvalue_get_integer(&fi->value);
3005 if (hfinfo->bitmask) {
3006 /* Figure out the bit width */
3007 bitwidth = hfinfo_bitwidth(hfinfo);
3010 unshifted_value = value;
3011 if (hfinfo->bitshift > 0) {
3012 unshifted_value <<= hfinfo->bitshift;
3015 /* Create the bitfield first */
3016 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
3017 bitfield_byte_length = p - label_str;
3020 /* Fill in the textual info */
3021 ret = snprintf(p, ITEM_LABEL_LENGTH - bitfield_byte_length,
3022 "%s: %s", hfinfo->name,
3023 value ? tfstring->true_string : tfstring->false_string);
3024 if ((ret == -1) || (ret >= (ITEM_LABEL_LENGTH - bitfield_byte_length)))
3025 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
3029 /* Fills data for bitfield ints with val_strings */
3031 fill_label_enumerated_bitfield(field_info *fi, gchar *label_str)
3033 char *format = NULL, *p;
3034 int bitfield_byte_length, bitwidth;
3035 guint32 unshifted_value;
3037 int ret; /*tmp return value */
3039 header_field_info *hfinfo = fi->hfinfo;
3041 /* Figure out the bit width */
3042 bitwidth = hfinfo_bitwidth(hfinfo);
3044 /* Pick the proper format string */
3045 format = hfinfo_uint_vals_format(hfinfo);
3048 unshifted_value = fvalue_get_integer(&fi->value);
3049 value = unshifted_value;
3050 if (hfinfo->bitshift > 0) {
3051 unshifted_value <<= hfinfo->bitshift;
3054 /* Create the bitfield first */
3055 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
3056 bitfield_byte_length = p - label_str;
3058 /* Fill in the textual info using stored (shifted) value */
3059 ret = snprintf(p, ITEM_LABEL_LENGTH - bitfield_byte_length,
3060 format, hfinfo->name,
3061 val_to_str(value, cVALS(hfinfo->strings), "Unknown"), value);
3062 if ((ret == -1) || (ret >= (ITEM_LABEL_LENGTH - bitfield_byte_length)))
3063 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
3067 fill_label_numeric_bitfield(field_info *fi, gchar *label_str)
3069 char *format = NULL, *p;
3070 int bitfield_byte_length, bitwidth;
3071 guint32 unshifted_value;
3073 int ret; /*tmp return value */
3075 header_field_info *hfinfo = fi->hfinfo;
3077 /* Figure out the bit width */
3078 bitwidth = hfinfo_bitwidth(hfinfo);
3080 /* Pick the proper format string */
3081 format = hfinfo_uint_format(hfinfo);
3084 unshifted_value = fvalue_get_integer(&fi->value);
3085 value = unshifted_value;
3086 if (hfinfo->bitshift > 0) {
3087 unshifted_value <<= hfinfo->bitshift;
3090 /* Create the bitfield using */
3091 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
3092 bitfield_byte_length = p - label_str;
3094 /* Fill in the textual info using stored (shifted) value */
3095 ret = snprintf(p, ITEM_LABEL_LENGTH - bitfield_byte_length,
3096 format, hfinfo->name, value);
3097 if ((ret == -1) || (ret >= (ITEM_LABEL_LENGTH - bitfield_byte_length)))
3098 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
3103 fill_label_enumerated_uint(field_info *fi, gchar *label_str)
3105 char *format = NULL;
3106 header_field_info *hfinfo = fi->hfinfo;
3108 int ret; /*tmp return value */
3110 /* Pick the proper format string */
3111 format = hfinfo_uint_vals_format(hfinfo);
3113 value = fvalue_get_integer(&fi->value);
3115 /* Fill in the textual info */
3116 ret = snprintf(label_str, ITEM_LABEL_LENGTH,
3117 format, hfinfo->name,
3118 val_to_str(value, cVALS(hfinfo->strings), "Unknown"), value);
3119 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
3120 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
3124 fill_label_uint(field_info *fi, gchar *label_str)
3126 char *format = NULL;
3127 header_field_info *hfinfo = fi->hfinfo;
3129 int ret; /*tmp return value */
3131 /* Pick the proper format string */
3132 format = hfinfo_uint_format(hfinfo);
3133 value = fvalue_get_integer(&fi->value);
3135 /* Fill in the textual info */
3136 ret = snprintf(label_str, ITEM_LABEL_LENGTH,
3137 format, hfinfo->name, value);
3138 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
3139 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
3143 fill_label_uint64(field_info *fi, gchar *label_str)
3145 char *format = NULL;
3146 header_field_info *hfinfo = fi->hfinfo;
3148 int ret; /*tmp return value */
3150 /* Pick the proper format string */
3151 format = hfinfo_uint64_format(hfinfo);
3152 value = fvalue_get_integer64(&fi->value);
3154 /* Fill in the textual info */
3155 ret = snprintf(label_str, ITEM_LABEL_LENGTH,
3156 format, hfinfo->name, value);
3157 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
3158 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
3162 fill_label_enumerated_int(field_info *fi, gchar *label_str)
3164 char *format = NULL;
3165 header_field_info *hfinfo = fi->hfinfo;
3167 int ret; /*tmp return value */
3169 /* Pick the proper format string */
3170 format = hfinfo_int_vals_format(hfinfo);
3171 value = fvalue_get_integer(&fi->value);
3173 /* Fill in the textual info */
3174 ret = snprintf(label_str, ITEM_LABEL_LENGTH,
3175 format, hfinfo->name,
3176 val_to_str(value, cVALS(hfinfo->strings), "Unknown"), value);
3177 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
3178 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
3182 fill_label_int(field_info *fi, gchar *label_str)
3184 char *format = NULL;
3185 header_field_info *hfinfo = fi->hfinfo;
3187 int ret; /*tmp return value */
3189 /* Pick the proper format string */
3190 format = hfinfo_int_format(hfinfo);
3191 value = fvalue_get_integer(&fi->value);
3193 /* Fill in the textual info */
3194 ret = snprintf(label_str, ITEM_LABEL_LENGTH,
3195 format, hfinfo->name, value);
3196 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
3197 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
3201 fill_label_int64(field_info *fi, gchar *label_str)
3203 char *format = NULL;
3204 header_field_info *hfinfo = fi->hfinfo;
3206 int ret; /*tmp return value */
3208 /* Pick the proper format string */
3209 format = hfinfo_int64_format(hfinfo);
3210 value = fvalue_get_integer64(&fi->value);
3212 /* Fill in the textual info */
3213 ret = snprintf(label_str, ITEM_LABEL_LENGTH,
3214 format, hfinfo->name, value);
3215 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
3216 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
3220 hfinfo_bitwidth(header_field_info *hfinfo)
3224 if (!hfinfo->bitmask) {
3228 switch(hfinfo->type) {
3246 bitwidth = hfinfo->display; /* hacky? :) */
3249 DISSECTOR_ASSERT_NOT_REACHED();
3256 hfinfo_uint_vals_format(header_field_info *hfinfo)
3258 char *format = NULL;
3260 switch(hfinfo->display) {
3262 format = "%s: %s (%u)";
3264 case BASE_OCT: /* I'm lazy */
3265 format = "%s: %s (%o)";
3268 switch(hfinfo->type) {
3270 format = "%s: %s (0x%02x)";
3273 format = "%s: %s (0x%04x)";
3276 format = "%s: %s (0x%06x)";
3279 format = "%s: %s (0x%08x)";
3282 DISSECTOR_ASSERT_NOT_REACHED();
3287 DISSECTOR_ASSERT_NOT_REACHED();
3294 hfinfo_uint_format(header_field_info *hfinfo)
3296 char *format = NULL;
3298 /* Pick the proper format string */
3299 if (hfinfo->type == FT_FRAMENUM) {
3301 * Frame numbers are always displayed in decimal.
3305 switch(hfinfo->display) {
3309 case BASE_OCT: /* I'm lazy */
3313 switch(hfinfo->type) {
3315 format = "%s: 0x%02x";
3318 format = "%s: 0x%04x";
3321 format = "%s: 0x%06x";
3324 format = "%s: 0x%08x";
3327 DISSECTOR_ASSERT_NOT_REACHED();
3332 DISSECTOR_ASSERT_NOT_REACHED();
3340 hfinfo_int_vals_format(header_field_info *hfinfo)
3342 char *format = NULL;
3344 switch(hfinfo->display) {
3346 format = "%s: %s (%d)";
3348 case BASE_OCT: /* I'm lazy */
3349 format = "%s: %s (%o)";
3352 switch(hfinfo->type) {
3354 format = "%s: %s (0x%02x)";
3357 format = "%s: %s (0x%04x)";
3360 format = "%s: %s (0x%06x)";
3363 format = "%s: %s (0x%08x)";
3366 DISSECTOR_ASSERT_NOT_REACHED();
3371 DISSECTOR_ASSERT_NOT_REACHED();
3378 hfinfo_uint64_format(header_field_info *hfinfo)
3380 char *format = NULL;
3382 /* Pick the proper format string */
3383 switch(hfinfo->display) {
3385 format = "%s: %" PRIu64;
3387 case BASE_OCT: /* I'm lazy */
3388 format = "%s: %" PRIo64;
3391 format = "%s: 0x%016" PRIx64;
3394 DISSECTOR_ASSERT_NOT_REACHED();
3401 hfinfo_int_format(header_field_info *hfinfo)
3403 char *format = NULL;
3405 /* Pick the proper format string */
3406 switch(hfinfo->display) {
3410 case BASE_OCT: /* I'm lazy */
3414 switch(hfinfo->type) {
3416 format = "%s: 0x%02x";
3419 format = "%s: 0x%04x";
3422 format = "%s: 0x%06x";
3425 format = "%s: 0x%08x";
3428 DISSECTOR_ASSERT_NOT_REACHED();
3433 DISSECTOR_ASSERT_NOT_REACHED();
3440 hfinfo_int64_format(header_field_info *hfinfo)
3442 char *format = NULL;
3444 /* Pick the proper format string */
3445 switch(hfinfo->display) {
3447 format = "%s: %" PRId64;
3449 case BASE_OCT: /* I'm lazy */
3450 format = "%s: %" PRIo64;
3453 format = "%s: 0x%016" PRIx64;
3456 DISSECTOR_ASSERT_NOT_REACHED();
3465 proto_registrar_n(void)
3467 return gpa_hfinfo.len;
3471 proto_registrar_get_name(int n)
3473 header_field_info *hfinfo;
3475 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
3476 return hfinfo->name;
3480 proto_registrar_get_abbrev(int n)
3482 header_field_info *hfinfo;
3484 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
3485 return hfinfo->abbrev;
3489 proto_registrar_get_ftype(int n)
3491 header_field_info *hfinfo;
3493 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
3494 return hfinfo->type;
3498 proto_registrar_get_parent(int n)
3500 header_field_info *hfinfo;
3502 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
3503 return hfinfo->parent;
3507 proto_registrar_is_protocol(int n)
3509 header_field_info *hfinfo;
3511 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
3512 return (hfinfo->parent == -1 ? TRUE : FALSE);
3515 /* Returns length of field in packet (not necessarily the length
3516 * in our internal representation, as in the case of IPv4).
3517 * 0 means undeterminable at time of registration
3518 * -1 means the field is not registered. */
3520 proto_registrar_get_length(int n)
3522 header_field_info *hfinfo;
3524 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
3525 return ftype_length(hfinfo->type);
3530 /* Looks for a protocol or a field in a proto_tree. Returns TRUE if
3531 * it exists anywhere, or FALSE if it exists nowhere. */
3533 proto_check_for_protocol_or_field(proto_tree* tree, int id)
3535 GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
3540 else if (g_ptr_array_len(ptrs) > 0) {
3548 /* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
3549 * This only works if the hfindex was "primed" before the dissection
3550 * took place, as we just pass back the already-created GPtrArray*.
3551 * The caller should *not* free the GPtrArray*; proto_tree_free_node()
3554 proto_get_finfo_ptr_array(proto_tree *tree, int id)
3556 return g_hash_table_lookup(PTREE_DATA(tree)->interesting_hfids,
3557 GINT_TO_POINTER(id));
3561 /* Helper struct and function for proto_find_info() */
3568 find_finfo(proto_node *node, gpointer data)
3570 field_info *fi = PITEM_FINFO(node);
3571 if (fi && fi->hfinfo) {
3572 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
3573 g_ptr_array_add(((ffdata_t*)data)->array, fi);
3577 /* Don't stop traversing. */
3581 /* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
3582 * This works on any proto_tree, primed or unprimed, but actually searches
3583 * the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
3584 * The caller does need to free the returned GPtrArray with
3585 * g_ptr_array_free(<array>, FALSE).
3588 proto_find_finfo(proto_tree *tree, int id)
3592 ffdata.array = g_ptr_array_new();
3595 proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
3597 return ffdata.array;
3608 check_for_offset(proto_node *node, gpointer data)
3610 field_info *fi = PITEM_FINFO(node);
3611 offset_search_t *offsearch = data;
3613 /* !fi == the top most container node which holds nothing */
3614 if (fi && !PROTO_ITEM_IS_HIDDEN(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
3615 if (offsearch->offset >= (guint) fi->start &&
3616 offsearch->offset < (guint) (fi->start + fi->length)) {
3618 offsearch->finfo = fi;
3619 return FALSE; /* keep traversing */
3622 return FALSE; /* keep traversing */
3625 /* Search a proto_tree backwards (from leaves to root) looking for the field
3626 * whose start/length occupies 'offset' */
3627 /* XXX - I couldn't find an easy way to search backwards, so I search
3628 * forwards, w/o stopping. Therefore, the last finfo I find will the be
3629 * the one I want to return to the user. This algorithm is inefficient
3630 * and could be re-done, but I'd have to handle all the children and
3631 * siblings of each node myself. When I have more time I'll do that.
3634 proto_find_field_from_offset(proto_tree *tree, guint offset, tvbuff_t *tvb)
3636 offset_search_t offsearch;
3638 offsearch.offset = offset;
3639 offsearch.finfo = NULL;
3640 offsearch.tvb = tvb;
3642 proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
3644 return offsearch.finfo;
3647 /* Dumps the protocols in the registration database to stdout. An independent
3648 * program can take this output and format it into nice tables or HTML or
3651 * There is one record per line. The fields are tab-delimited.
3653 * Field 1 = protocol name
3654 * Field 2 = protocol short name
3655 * Field 3 = protocol filter name
3658 proto_registrar_dump_protocols(void)
3660 protocol_t *protocol;
3664 for (i = proto_get_first_protocol(&cookie); i != -1;
3665 i = proto_get_next_protocol(&cookie)) {
3666 protocol = find_protocol_by_id(i);
3667 printf("%s\t%s\t%s\n", protocol->name, protocol->short_name,
3668 protocol->filter_name);
3672 /* Dumps the value_string and true/false strings for fields that have
3673 * them. There is one record per line. Fields are tab-delimited.
3674 * There are two types of records, Value String records and True/False
3675 * String records. The first field, 'V' or 'T', indicates the type
3681 * Field 2 = field abbreviation to which this value string corresponds
3682 * Field 3 = Integer value
3685 * True/False Strings
3686 * ------------------
3688 * Field 2 = field abbreviation to which this true/false string corresponds
3689 * Field 3 = True String
3690 * Field 4 = False String
3693 proto_registrar_dump_values(void)
3695 header_field_info *hfinfo, *parent_hfinfo;
3697 const value_string *vals;
3698 const true_false_string *tfs;
3700 len = gpa_hfinfo.len;
3701 for (i = 0; i < len ; i++) {
3702 PROTO_REGISTRAR_GET_NTH(i, hfinfo);
3704 if (hfinfo->id == hf_text_only) {
3708 /* ignore protocols */
3709 if (proto_registrar_is_protocol(i)) {
3712 /* process header fields */
3715 * If this field isn't at the head of the list of
3716 * fields with this name, skip this field - all
3717 * fields with the same name are really just versions
3718 * of the same field stored in different bits, and
3719 * should have the same type/radix/value list, and
3720 * just differ in their bit masks. (If a field isn't
3721 * a bitfield, but can be, say, 1 or 2 bytes long,
3722 * it can just be made FT_UINT16, meaning the
3723 * *maximum* length is 2 bytes, and be used
3726 if (hfinfo->same_name_prev != NULL)
3729 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
3734 if (hfinfo->type == FT_UINT8 ||
3735 hfinfo->type == FT_UINT16 ||
3736 hfinfo->type == FT_UINT24 ||
3737 hfinfo->type == FT_UINT32 ||
3738 hfinfo->type == FT_UINT64 ||
3739 hfinfo->type == FT_INT8 ||
3740 hfinfo->type == FT_INT16 ||
3741 hfinfo->type == FT_INT24 ||
3742 hfinfo->type == FT_INT32 ||
3743 hfinfo->type == FT_INT64) {
3745 vals = hfinfo->strings;
3747 else if (hfinfo->type == FT_BOOLEAN) {
3748 tfs = hfinfo->strings;
3751 /* Print value strings? */
3754 while (vals[vi].strptr) {
3755 /* Print in the proper base */
3756 if (hfinfo->display == BASE_HEX) {
3757 printf("V\t%s\t0x%x\t%s\n",
3763 printf("V\t%s\t%u\t%s\n",
3772 /* Print true/false strings? */
3774 printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
3775 tfs->true_string, tfs->false_string);
3781 /* Dumps the contents of the registration database to stdout. An indepedent
3782 * program can take this output and format it into nice tables or HTML or
3785 * There is one record per line. Each record is either a protocol or a header
3786 * field, differentiated by the first field. The fields are tab-delimited.
3791 * Field 2 = descriptive protocol name
3792 * Field 3 = protocol abbreviation
3798 * Field 2 = descriptive field name
3799 * Field 3 = field abbreviation
3800 * Field 4 = type ( textual representation of the the ftenum type )
3801 * Field 5 = parent protocol abbreviation
3803 * (format 2 adds these fields:)
3804 * Field 6 = base for display (for integer types)
3805 * Field 7 = blurb describing field
3808 proto_registrar_dump_fields(int format)
3810 header_field_info *hfinfo, *parent_hfinfo;
3812 const char *enum_name;
3813 const char *base_name;
3815 len = gpa_hfinfo.len;
3816 for (i = 0; i < len ; i++) {
3817 PROTO_REGISTRAR_GET_NTH(i, hfinfo);
3820 * Skip fields with zero-length names or abbreviations;
3821 * the pseudo-field for "proto_tree_add_text()" is such
3822 * a field, and we don't want it in the list of filterable
3826 * XXX - perhaps the name and abbrev field should be null
3827 * pointers rather than null strings for that pseudo-field,
3828 * but we'd have to add checks for null pointers in some
3829 * places if we did that.
3831 * Or perhaps protocol tree items added with
3832 * "proto_tree_add_text()" should have -1 as the field index,
3833 * with no pseudo-field being used, but that might also
3834 * require special checks for -1 to be added.
3836 /* XXX - we could just skip the special text
3837 * pseudo-field by testing: if (hfinfo->id == hf_text_only)
3839 if (hfinfo->name[0] == 0 || hfinfo->abbrev[0] == 0)
3842 /* format for protocols */
3843 if (proto_registrar_is_protocol(i)) {
3844 printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
3846 /* format for header fields */
3849 * If this field isn't at the head of the list of
3850 * fields with this name, skip this field - all
3851 * fields with the same name are really just versions
3852 * of the same field stored in different bits, and
3853 * should have the same type/radix/value list, and
3854 * just differ in their bit masks. (If a field isn't
3855 * a bitfield, but can be, say, 1 or 2 bytes long,
3856 * it can just be made FT_UINT16, meaning the
3857 * *maximum* length is 2 bytes, and be used
3860 if (hfinfo->same_name_prev != NULL)
3863 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
3865 enum_name = ftype_name(hfinfo->type);
3869 if (hfinfo->type == FT_UINT8 ||
3870 hfinfo->type == FT_UINT16 ||
3871 hfinfo->type == FT_UINT24 ||
3872 hfinfo->type == FT_UINT32 ||
3873 hfinfo->type == FT_UINT64 ||
3874 hfinfo->type == FT_INT8 ||
3875 hfinfo->type == FT_INT16 ||
3876 hfinfo->type == FT_INT24 ||
3877 hfinfo->type == FT_INT32 ||
3878 hfinfo->type == FT_INT64) {
3881 switch(hfinfo->display) {
3883 base_name = "BASE_NONE";
3886 base_name = "BASE_DEC";
3889 base_name = "BASE_HEX";
3892 base_name = "BASE_OCT";
3899 printf("F\t%s\t%s\t%s\t%s\t%s\n", hfinfo->name, hfinfo->abbrev,
3900 enum_name,parent_hfinfo->abbrev, hfinfo->blurb);
3902 else if (format == 2) {
3903 printf("F\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n",
3904 hfinfo->name, hfinfo->abbrev,
3905 enum_name,parent_hfinfo->abbrev, hfinfo->blurb,
3906 base_name, hfinfo->blurb);
3913 hfinfo_numeric_format(header_field_info *hfinfo)
3915 char *format = NULL;
3917 /* Pick the proper format string */
3918 if (hfinfo->type == FT_FRAMENUM) {
3920 * Frame numbers are always displayed in decimal.
3922 format = "%s == %u";
3924 /* Pick the proper format string */
3925 switch(hfinfo->display) {
3927 case BASE_OCT: /* I'm lazy */
3928 switch(hfinfo->type) {
3933 format = "%s == %u";
3936 format = "%s == %" PRIu64;
3942 format = "%s == %d";
3945 format = "%s == %" PRId64;
3948 DISSECTOR_ASSERT_NOT_REACHED();
3953 switch(hfinfo->type) {
3955 format = "%s == 0x%02x";
3958 format = "%s == 0x%04x";
3961 format = "%s == 0x%06x";
3964 format = "%s == 0x%08x";
3967 format = "%s == 0x%016" PRIx64;
3970 DISSECTOR_ASSERT_NOT_REACHED();
3975 DISSECTOR_ASSERT_NOT_REACHED();
3983 * Returns TRUE if we can do a "match selected" on the field, FALSE
3987 proto_can_match_selected(field_info *finfo, epan_dissect_t *edt)
3989 header_field_info *hfinfo;
3992 hfinfo = finfo->hfinfo;
3993 DISSECTOR_ASSERT(hfinfo);
3995 switch(hfinfo->type) {
4014 case FT_ABSOLUTE_TIME:
4015 case FT_RELATIVE_TIME:
4018 case FT_UINT_STRING:
4024 * These all have values, so we can match.
4030 * This doesn't have a value, so we'd match
4031 * on the raw bytes at this address.
4033 * Should we be allowed to access to the raw bytes?
4034 * If "edt" is NULL, the answer is "no".
4040 * Is this field part of the raw frame tvbuff?
4041 * If not, we can't use "frame[N:M]" to match
4044 * XXX - should this be frame-relative, or
4045 * protocol-relative?
4047 * XXX - does this fallback for non-registered
4048 * fields even make sense?
4050 if (finfo->ds_tvb != edt->tvb)
4054 * If the length is 0, there's nothing to match, so
4055 * we can't match. (Also check for negative values,
4056 * just in case, as we'll cast it to an unsigned
4059 length = finfo->length;
4064 * Don't go past the end of that tvbuff.
4066 if ((guint)length > tvb_length(finfo->ds_tvb))
4067 length = tvb_length(finfo->ds_tvb);
4075 proto_construct_dfilter_string(field_info *finfo, epan_dissect_t *edt)
4077 header_field_info *hfinfo;
4079 char *buf, *stringified, *format, *ptr;
4081 gint start, length, length_remaining;
4084 hfinfo = finfo->hfinfo;
4085 DISSECTOR_ASSERT(hfinfo);
4086 abbrev_len = strlen(hfinfo->abbrev);
4089 * XXX - we should add "val_to_string_repr" and "string_repr_len"
4090 * functions for more types, and use them whenever possible.
4092 * The FT_UINT and FT_INT types are the only tricky ones, as
4093 * we choose the base in the string expression based on the
4094 * display base of the field.
4096 * Note that the base does matter, as this is also used for
4097 * the protocolinfo tap.
4099 * It might be nice to use that in "proto_item_fill_label()"
4100 * as well, although, there, you'd have to deal with the base
4101 * *and* with resolved values for addresses.
4103 * Perhaps we need two different val_to_string routines, one
4104 * to generate items for display filters and one to generate
4105 * strings for display, and pass to both of them the
4106 * "display" and "strings" values in the header_field_info
4107 * structure for the field, so they can get the base and,
4108 * if the field is Boolean or an enumerated integer type,
4109 * the tables used to generate human-readable values.
4111 switch(hfinfo->type) {
4123 * 4 bytes for " == ".
4126 * a sign + up to 10 digits of 32-bit integer,
4129 * "0x" + 8 digits of 32-bit integer, in hex;
4131 * 11 digits of 32-bit integer, in octal.
4132 * (No, we don't do octal, but this way,
4133 * we know that if we do, this will still
4136 * 1 byte for the trailing '\0'.
4138 dfilter_len = abbrev_len + 4 + 11 + 1;
4139 buf = g_malloc0(dfilter_len);
4140 format = hfinfo_numeric_format(hfinfo);
4141 snprintf(buf, dfilter_len, format, hfinfo->abbrev, fvalue_get_integer(&finfo->value));
4147 * 4 bytes for " == ".
4150 * a sign + up to 20 digits of 32-bit integer,
4153 * "0x" + 16 digits of 32-bit integer, in hex;
4155 * 22 digits of 32-bit integer, in octal.
4156 * (No, we don't do octal, but this way,
4157 * we know that if we do, this will still
4160 * 1 byte for the trailing '\0'.
4162 dfilter_len = abbrev_len + 4 + 22 + 1;
4163 buf = g_malloc0(dfilter_len);
4164 format = hfinfo_numeric_format(hfinfo);
4165 snprintf(buf, dfilter_len, format, hfinfo->abbrev, fvalue_get_integer64(&finfo->value));
4170 * 4 bytes for " == ".
4172 * 8 bytes for 8 digits of 32-bit hex number.
4173 * 1 byte for the trailing '\0'.
4175 dfilter_len = abbrev_len + 4 + 2 + 8 + 1;
4176 buf = g_malloc0(dfilter_len);
4177 snprintf(buf, dfilter_len, "%s == 0x%08x", hfinfo->abbrev,
4178 fvalue_get_integer(&finfo->value));
4183 * 4 bytes for " == ".
4184 * N bytes for the string for the address.
4185 * 1 byte for the trailing '\0'.
4187 stringified = ip6_to_str((struct e_in6_addr*) fvalue_get(&finfo->value));
4188 dfilter_len = abbrev_len + 4 + strlen(stringified) + 1;
4189 buf = g_malloc0(dfilter_len);
4190 snprintf(buf, dfilter_len, "%s == %s", hfinfo->abbrev,
4194 /* These use the fvalue's "to_string_repr" method. */
4202 case FT_ABSOLUTE_TIME:
4203 case FT_RELATIVE_TIME:
4205 /* Figure out the string length needed.
4206 * The ft_repr length.
4207 * 4 bytes for " == ".
4208 * 1 byte for trailing NUL.
4210 dfilter_len = fvalue_string_repr_len(&finfo->value,
4212 dfilter_len += abbrev_len + 4 + 1;
4213 buf = g_malloc0(dfilter_len);
4215 /* Create the string */
4216 snprintf(buf, dfilter_len, "%s == ", hfinfo->abbrev);
4217 fvalue_to_string_repr(&finfo->value,
4219 &buf[abbrev_len + 4]);
4223 buf = g_strdup(finfo->hfinfo->abbrev);
4228 * This doesn't have a value, so we'd match
4229 * on the raw bytes at this address.
4231 * Should we be allowed to access to the raw bytes?
4232 * If "edt" is NULL, the answer is "no".
4238 * Is this field part of the raw frame tvbuff?
4239 * If not, we can't use "frame[N:M]" to match
4242 * XXX - should this be frame-relative, or
4243 * protocol-relative?
4245 * XXX - does this fallback for non-registered
4246 * fields even make sense?
4248 if (finfo->ds_tvb != edt->tvb)
4249 return NULL; /* you lose */
4252 * If the length is 0, there's nothing to match, so
4253 * we can't match. (Also check for negative values,
4254 * just in case, as we'll cast it to an unsigned
4257 length = finfo->length;
4262 * Don't go past the end of that tvbuff.
4264 length_remaining = tvb_length_remaining(finfo->ds_tvb, finfo->start);
4265 if (length > length_remaining)
4266 length = length_remaining;
4270 start = finfo->start;
4271 buf = g_malloc0(32 + length * 3);
4274 sprintf(ptr, "frame[%d:%d] == ", finfo->start, length);
4275 ptr = buf+strlen(buf);
4277 for (i=0;i<length; i++) {
4278 c = tvb_get_guint8(finfo->ds_tvb, start);
4281 sprintf(ptr, "%02x", c);
4284 sprintf(ptr, ":%02x", c);
4286 ptr = buf+strlen(buf);