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;
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 /* initialize data structures and register protocols and fields */
212 proto_init(const char *plugin_dir
217 void (register_all_protocols)(void),
218 void (register_all_protocol_handoffs)(void))
220 static hf_register_info hf[] = {
222 { "", "", FT_NONE, BASE_NONE, NULL, 0x0,
228 gmc_hfinfo = g_mem_chunk_new("gmc_hfinfo",
229 sizeof(header_field_info),
230 INITIAL_NUM_PROTOCOL_HFINFO * sizeof(header_field_info),
234 gpa_hfinfo.allocated_len=0;
236 gpa_name_tree = g_tree_new(g_strcmp);
238 /* Initialize the ftype subsystem */
241 /* Register one special-case FT_TEXT_ONLY field for use when
242 converting ethereal to new-style proto_tree. These fields
243 are merely strings on the GUI tree; they are not filterable */
244 proto_register_field_array(-1, hf, array_length(hf));
246 /* Have each built-in dissector register its protocols, fields,
247 dissector tables, and dissectors to be called through a
248 handle, and do whatever one-time initialization it needs to
250 register_all_protocols();
253 /* Now scan for plugins and load all the ones we find, calling
254 their register routines to do the stuff described above. */
255 init_plugins(plugin_dir);
258 /* Now call the "handoff registration" routines of all built-in
259 dissectors; those routines register the dissector in other
260 dissectors' handoff tables, and fetch any dissector handles
262 register_all_protocol_handoffs();
265 /* Now do the same with plugins. */
266 register_all_plugin_handoffs();
269 /* We've assigned all the subtree type values; allocate the array
270 for them, and zero it out. */
271 tree_is_expanded = g_malloc(num_tree_types*sizeof (gint *));
272 memset(tree_is_expanded, 0, num_tree_types*sizeof (gint *));
275 /* String comparison func for dfilter_token GTree */
277 g_strcmp(gconstpointer a, gconstpointer b)
279 return strcmp((const char*)a, (const char*)b);
285 /* Free the abbrev/ID GTree */
287 g_tree_destroy(gpa_name_tree);
288 gpa_name_tree = NULL;
292 g_mem_chunk_destroy(gmc_hfinfo);
294 if(gpa_hfinfo.allocated_len){
296 gpa_hfinfo.allocated_len=0;
297 g_free(gpa_hfinfo.hfi);
300 if (tree_is_expanded != NULL)
301 g_free(tree_is_expanded);
305 typedef gboolean (*proto_tree_traverse_func)(proto_node *, gpointer);
308 proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
311 proto_node *pnode = tree;
315 if (func(pnode, data))
318 child = pnode->first_child;
319 while (child != NULL) {
321 * The routine we call might modify the child, e.g. by
322 * freeing it, so we get the child's successor before
323 * calling that routine.
326 child = current->next;
327 if (proto_tree_traverse_pre_order((proto_tree *)current, func,
336 proto_tree_traverse_in_order(proto_tree *tree, proto_tree_traverse_func func,
339 proto_node *pnode = tree;
343 child = pnode->first_child;
346 * The routine we call might modify the child, e.g. by
347 * freeing it, so we get the child's successor before
348 * calling that routine.
351 child = current->next;
353 if (proto_tree_traverse_in_order((proto_tree *)current, func,
357 if (func(pnode, data))
360 while (child != NULL) {
362 * The routine we call might modify the child, e.g. by
363 * freeing it, so we get the child's successor before
364 * calling that routine.
367 child = current->next;
368 if (proto_tree_traverse_in_order((proto_tree *)current,
373 if (func(pnode, data))
381 proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
384 proto_node *node = tree;
387 node = node->first_child;
388 while (node != NULL) {
390 node = current->next;
391 func((proto_tree *)current, data);
395 /* frees the resources that the dissection a proto_tree uses */
397 proto_tree_free(proto_tree *tree)
399 proto_tree_traverse_in_order(tree, proto_tree_free_node, NULL);
403 free_GPtrArray_value(gpointer key _U_, gpointer value, gpointer user_data _U_)
405 GPtrArray *ptrs = value;
407 g_ptr_array_free(ptrs, TRUE);
411 free_node_tree_data(tree_data_t *tree_data)
413 /* Free all the GPtrArray's in the interesting_hfids hash. */
414 g_hash_table_foreach(tree_data->interesting_hfids,
415 free_GPtrArray_value, NULL);
417 /* And then destroy the hash. */
418 g_hash_table_destroy(tree_data->interesting_hfids);
420 /* And finally the tree_data_t itself. */
424 #define FREE_NODE_FIELD_INFO(finfo) \
426 ITEM_LABEL_FREE(finfo->rep); \
428 FVALUE_CLEANUP(&finfo->value); \
429 FIELD_INFO_FREE(finfo);
432 proto_tree_free_node(proto_node *node, gpointer data _U_)
434 field_info *finfo = PITEM_FINFO(node);
437 /* This is the root node. Destroy the per-tree data.
438 * There is no field_info to destroy. */
439 free_node_tree_data(PTREE_DATA(node));
442 /* This is a child node. Don't free the per-tree data, but
443 * do free the field_info data. */
444 FREE_NODE_FIELD_INFO(finfo);
447 /* Free the proto_node. */
448 PROTO_NODE_FREE(node);
450 return FALSE; /* FALSE = do not end traversal of protocol tree */
453 /* Is the parsing being done for a visible proto_tree or an invisible one?
454 * By setting this correctly, the proto_tree creation is sped up by not
455 * having to call vsnprintf and copy strings around.
458 proto_tree_set_visible(proto_tree *tree, gboolean visible)
460 PTREE_DATA(tree)->visible = visible;
463 #define PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo) \
464 g_assert((guint)hfindex < gpa_hfinfo.len); \
465 hfinfo=gpa_hfinfo.hfi[hfindex];
467 /* Finds a record in the hf_info_records array by id. */
469 proto_registrar_get_nth(guint hfindex)
471 register header_field_info *hfinfo;
473 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
477 /* Finds a record in the hf_info_records array by name.
480 proto_registrar_get_byname(char *field_name)
482 g_assert(field_name != NULL);
483 return g_tree_lookup(gpa_name_tree, field_name);
486 /* Add a text-only node, leaving it to our caller to fill the text in */
488 proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, gint start, gint length)
492 pi = proto_tree_add_pi(tree, hf_text_only, tvb, start, &length, NULL);
499 /* Add a text-only node to the proto_tree */
501 proto_tree_add_text(proto_tree *tree, tvbuff_t *tvb, gint start, gint length,
502 const char *format, ...)
507 pi = proto_tree_add_text_node(tree, tvb, start, length);
511 va_start(ap, format);
512 proto_tree_set_representation(pi, format, ap);
518 /* Add a text-only node to the proto_tree (va_list version) */
520 proto_tree_add_text_valist(proto_tree *tree, tvbuff_t *tvb, gint start,
521 gint length, const char *format, va_list ap)
525 pi = proto_tree_add_text_node(tree, tvb, start, length);
529 proto_tree_set_representation(pi, format, ap);
534 /* Add a text-only node for debugging purposes. The caller doesn't need
535 * to worry about tvbuff, start, or length. Debug message gets sent to
538 proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
543 pi = proto_tree_add_text_node(tree, NULL, 0, 0);
547 va_start(ap, format);
548 proto_tree_set_representation(pi, format, ap);
558 get_uint_value(tvbuff_t *tvb, gint offset, gint length, gboolean little_endian)
565 value = tvb_get_guint8(tvb, offset);
569 value = little_endian ? tvb_get_letohs(tvb, offset)
570 : tvb_get_ntohs(tvb, offset);
574 value = little_endian ? tvb_get_letoh24(tvb, offset)
575 : tvb_get_ntoh24(tvb, offset);
579 value = little_endian ? tvb_get_letohl(tvb, offset)
580 : tvb_get_ntohl(tvb, offset);
584 g_assert_not_reached();
592 get_int_value(tvbuff_t *tvb, gint offset, gint length, gboolean little_endian)
599 value = (gint8)tvb_get_guint8(tvb, offset);
603 value = (gint16) (little_endian ? tvb_get_letohs(tvb, offset)
604 : tvb_get_ntohs(tvb, offset));
608 value = little_endian ? tvb_get_letoh24(tvb, offset)
609 : tvb_get_ntoh24(tvb, offset);
610 if (value & 0x00800000) {
611 /* Sign bit is set; sign-extend it. */
617 value = little_endian ? tvb_get_letohl(tvb, offset)
618 : tvb_get_ntohl(tvb, offset);
622 g_assert_not_reached();
629 /* Add an item to a proto_tree, using the text label registered to that item;
630 the item is extracted from the tvbuff handed to it. */
632 proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
633 gint start, gint length, gboolean little_endian)
647 new_fi = alloc_field_info(tree, hfindex, tvb, start, &length);
652 /* there is a possibility here that we might raise an exception
653 * and thus would lose track of the field_info.
654 * store it in a temp so that if we come here again we can reclaim
655 * the field_info without leaking memory.
657 /* XXX this only keeps track of one field_info struct,
658 if we ever go multithreaded for calls to this function
659 we have to change this code to use per thread variable.
662 /* oops, last one we got must have been lost due
664 * good thing we saved it, now we can reverse the
665 * memory leak and reclaim it.
667 SLAB_FREE(field_info_tmp, field_info);
669 /* we might throw an exception, keep track of this one
670 * across the "dangerous" section below.
672 field_info_tmp=new_fi;
674 switch(new_fi->hfinfo->type) {
676 /* no value to set for FT_NONE */
680 proto_tree_set_protocol_tvb(new_fi, tvb);
684 proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
688 n = get_uint_value(tvb, start, length, little_endian);
689 proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
691 /* Instead of calling proto_item_set_len(), since we don't yet
692 * have a proto_item, we set the field_info's length ourselves. */
693 new_fi->length = n + length;
697 proto_tree_set_boolean(new_fi,
698 get_uint_value(tvb, start, length, little_endian));
701 /* XXX - make these just FT_UINT? */
706 proto_tree_set_uint(new_fi,
707 get_uint_value(tvb, start, length, little_endian));
712 g_assert(length == 8);
713 proto_tree_set_uint64_tvb(new_fi, tvb, start, little_endian);
716 /* XXX - make these just FT_INT? */
721 proto_tree_set_int(new_fi,
722 get_int_value(tvb, start, length, little_endian));
726 g_assert(length == 4);
727 tvb_memcpy(tvb, (guint8 *)&value, start, 4);
728 proto_tree_set_ipv4(new_fi, little_endian ? GUINT32_SWAP_LE_BE(value) : value);
732 g_assert(length == 4);
733 proto_tree_set_ipxnet(new_fi,
734 get_uint_value(tvb, start, 4, FALSE));
738 g_assert(length == 16);
739 proto_tree_set_ipv6_tvb(new_fi, tvb, start);
743 g_assert(length == 6);
744 proto_tree_set_ether_tvb(new_fi, tvb, start);
748 g_assert(length == 4);
750 floatval = tvb_get_letohieee_float(tvb, start);
752 floatval = tvb_get_ntohieee_float(tvb, start);
753 proto_tree_set_float(new_fi, floatval);
757 g_assert(length == 8);
759 doubleval = tvb_get_letohieee_double(tvb, start);
761 doubleval = tvb_get_ntohieee_double(tvb, start);
762 proto_tree_set_double(new_fi, doubleval);
766 /* This g_strdup'ed memory is freed in proto_tree_free_node() */
767 proto_tree_set_string_tvb(new_fi, tvb, start, length);
771 if (length != 0) { /* XXX - Should we throw an exception instead? */
772 /* Instead of calling proto_item_set_len(),
773 * since we don't yet have a proto_item, we
774 * set the field_info's length ourselves.
776 * XXX - our caller can't use that length to
777 * advance an offset unless they arrange that
778 * there always be a protocol tree into which
779 * we're putting this item.
782 /* This can throw an exception */
783 length = tvb_strsize(tvb, start);
785 /* This g_malloc'ed memory is freed
786 in proto_tree_free_node() */
787 string = g_malloc(length);
789 tvb_memcpy(tvb, string, start, length);
790 new_fi->length = length;
793 /* In this case, length signifies
794 * the length of the string.
796 * This could either be a null-padded
797 * string, which doesn't necessarily
798 * have a '\0' at the end, or a
799 * null-terminated string, with a
800 * trailing '\0'. (Yes, there are
801 * cases where you have a string
802 * that's both counted and null-
805 * In the first case, we must
806 * allocate a buffer of length
807 * "length+1", to make room for
810 * In the second case, we don't
811 * assume that there is a trailing
812 * '\0' there, as the packet might
813 * be malformed. (XXX - should we
814 * throw an exception if there's no
815 * trailing '\0'?) Therefore, we
816 * allocate a buffer of length
817 * "length+1", and put in a trailing
818 * '\0', just to be safe.
820 * (XXX - this would change if
821 * we made string values counted
822 * rather than null-terminated.)
825 /* This g_malloc'ed memory is freed
826 * in proto_tree_free_node() */
827 string = tvb_get_string(tvb, start,
829 new_fi->length = length;
831 proto_tree_set_string(new_fi, string, TRUE);
836 /* This g_strdup'ed memory is freed in proto_tree_free_node() */
837 n = get_uint_value(tvb, start, length, little_endian);
838 proto_tree_set_string_tvb(new_fi, tvb, start + length, n);
840 /* Instead of calling proto_item_set_len(), since we
841 * don't yet have a proto_item, we set the
842 * field_info's length ourselves.
844 * XXX - our caller can't use that length to
845 * advance an offset unless they arrange that
846 * there always be a protocol tree into which
847 * we're putting this item.
849 new_fi->length = n + length;
853 g_error("new_fi->hfinfo->type %d (%s) not handled\n",
854 new_fi->hfinfo->type,
855 ftype_name(new_fi->hfinfo->type));
856 g_assert_not_reached();
860 /* Don't add new node to proto_tree until now so that any exceptions
861 * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
862 pi = proto_tree_add_node(tree, new_fi);
864 /* we did not raise an exception so we dont have to remember this
865 * field_info struct any more.
869 /* If the proto_tree wants to keep a record of this finfo
870 * for quick lookup, then record it. */
871 hash = PTREE_DATA(tree)->interesting_hfids;
872 ptrs = g_hash_table_lookup(hash, GINT_TO_POINTER(hfindex));
874 g_ptr_array_add(ptrs, new_fi);
881 proto_tree_add_item_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb,
882 gint start, gint length, gboolean little_endian)
886 pi = proto_tree_add_item(tree, hfindex, tvb, start, length, little_endian);
890 PROTO_ITEM_SET_HIDDEN(pi);
896 /* Add a FT_NONE to a proto_tree */
898 proto_tree_add_none_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
899 gint length, const char *format, ...)
903 header_field_info *hfinfo;
908 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
909 g_assert(hfinfo->type == FT_NONE);
911 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, NULL);
913 va_start(ap, format);
914 proto_tree_set_representation(pi, format, ap);
917 /* no value to set for FT_NONE */
923 proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb)
925 fvalue_set(&fi->value, tvb, TRUE);
928 /* Add a FT_PROTOCOL to a proto_tree */
930 proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
931 gint length, const char *format, ...)
935 header_field_info *hfinfo;
941 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
942 g_assert(hfinfo->type == FT_PROTOCOL);
944 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
946 va_start(ap, format);
947 proto_tree_set_representation(pi, format, ap);
951 proto_tree_set_protocol_tvb(new_fi, tvb);
954 proto_tree_set_protocol_tvb(new_fi, NULL);
960 /* Add a FT_BYTES to a proto_tree */
962 proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
963 gint length, const guint8 *start_ptr)
967 header_field_info *hfinfo;
972 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
973 g_assert(hfinfo->type == FT_BYTES);
975 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
976 proto_tree_set_bytes(new_fi, start_ptr, length);
982 proto_tree_add_bytes_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
983 gint length, const guint8 *start_ptr)
987 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
991 PROTO_ITEM_SET_HIDDEN(pi);
997 proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
998 gint length, const guint8 *start_ptr, const char *format, ...)
1003 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
1007 va_start(ap, format);
1008 proto_tree_set_representation(pi, format, ap);
1015 proto_tree_set_bytes(field_info *fi, const guint8* start_ptr, gint length)
1019 bytes = g_byte_array_new();
1021 g_byte_array_append(bytes, start_ptr, length);
1023 fvalue_set(&fi->value, bytes, TRUE);
1028 proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, gint offset, gint length)
1030 proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
1033 /* Add a FT_*TIME to a proto_tree */
1035 proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1036 nstime_t *value_ptr)
1040 header_field_info *hfinfo;
1045 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
1046 g_assert(hfinfo->type == FT_ABSOLUTE_TIME ||
1047 hfinfo->type == FT_RELATIVE_TIME);
1049 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
1050 proto_tree_set_time(new_fi, value_ptr);
1056 proto_tree_add_time_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1057 nstime_t *value_ptr)
1061 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
1065 PROTO_ITEM_SET_HIDDEN(pi);
1071 proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1072 nstime_t *value_ptr, const char *format, ...)
1077 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
1081 va_start(ap, format);
1082 proto_tree_set_representation(pi, format, ap);
1088 /* Set the FT_*TIME value */
1090 proto_tree_set_time(field_info *fi, nstime_t *value_ptr)
1092 fvalue_set(&fi->value, value_ptr, FALSE);
1095 /* Add a FT_IPXNET to a proto_tree */
1097 proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1102 header_field_info *hfinfo;
1107 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
1108 g_assert(hfinfo->type == FT_IPXNET);
1110 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
1111 proto_tree_set_ipxnet(new_fi, value);
1117 proto_tree_add_ipxnet_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1122 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
1126 PROTO_ITEM_SET_HIDDEN(pi);
1132 proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1133 guint32 value, const char *format, ...)
1138 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
1142 va_start(ap, format);
1143 proto_tree_set_representation(pi, format, ap);
1149 /* Set the FT_IPXNET value */
1151 proto_tree_set_ipxnet(field_info *fi, guint32 value)
1153 fvalue_set_integer(&fi->value, value);
1156 /* Add a FT_IPv4 to a proto_tree */
1158 proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1163 header_field_info *hfinfo;
1168 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
1169 g_assert(hfinfo->type == FT_IPv4);
1171 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
1172 proto_tree_set_ipv4(new_fi, value);
1178 proto_tree_add_ipv4_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1183 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
1187 PROTO_ITEM_SET_HIDDEN(pi);
1193 proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1194 guint32 value, const char *format, ...)
1199 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
1203 va_start(ap, format);
1204 proto_tree_set_representation(pi, format, ap);
1210 /* Set the FT_IPv4 value */
1212 proto_tree_set_ipv4(field_info *fi, guint32 value)
1214 fvalue_set_integer(&fi->value, value);
1217 /* Add a FT_IPv6 to a proto_tree */
1219 proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1220 const guint8* value_ptr)
1224 header_field_info *hfinfo;
1229 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
1230 g_assert(hfinfo->type == FT_IPv6);
1232 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
1233 proto_tree_set_ipv6(new_fi, value_ptr);
1239 proto_tree_add_ipv6_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1240 const guint8* value_ptr)
1244 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
1248 PROTO_ITEM_SET_HIDDEN(pi);
1254 proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1255 const guint8* value_ptr, const char *format, ...)
1260 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
1264 va_start(ap, format);
1265 proto_tree_set_representation(pi, format, ap);
1271 /* Set the FT_IPv6 value */
1273 proto_tree_set_ipv6(field_info *fi, const guint8* value_ptr)
1275 fvalue_set(&fi->value, (gpointer) value_ptr, FALSE);
1279 proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, gint start)
1281 proto_tree_set_ipv6(fi, tvb_get_ptr(tvb, start, 16));
1285 proto_tree_set_uint64(field_info *fi, guint64 value)
1287 fvalue_set_integer64(&fi->value, value);
1291 proto_tree_set_uint64_tvb(field_info *fi, tvbuff_t *tvb, gint start, gboolean little_endian)
1295 value = little_endian ? tvb_get_letoh64(tvb, start)
1296 : tvb_get_ntoh64(tvb, start);
1298 proto_tree_set_uint64(fi, value);
1301 /* Add a FT_STRING or FT_STRINGZ to a proto_tree. Creates own copy of string,
1302 * and frees it when the proto_tree is destroyed. */
1304 proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
1305 gint length, const char* value)
1309 header_field_info *hfinfo;
1314 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
1315 g_assert(hfinfo->type == FT_STRING || hfinfo->type == FT_STRINGZ);
1317 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
1318 g_assert(length >= 0);
1319 proto_tree_set_string(new_fi, value, FALSE);
1325 proto_tree_add_string_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
1326 gint length, const char* value)
1330 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
1334 PROTO_ITEM_SET_HIDDEN(pi);
1340 proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
1341 gint length, const char* value, const char *format, ...)
1346 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
1350 va_start(ap, format);
1351 proto_tree_set_representation(pi, format, ap);
1357 /* Appends string data to a FT_STRING or FT_STRINGZ, allowing progressive
1358 * field info update instead of only updating the representation as does
1359 * proto_item_append_text()
1362 proto_item_append_string(proto_item *pi, const char *str)
1365 header_field_info *hfinfo;
1366 gchar *old_str, *new_str;
1373 fi = PITEM_FINFO(pi);
1374 hfinfo = fi->hfinfo;
1375 g_assert(hfinfo->type == FT_STRING || hfinfo->type == FT_STRINGZ);
1376 old_str = fvalue_get(&fi->value);
1377 new_str = g_malloc(strlen(old_str) + strlen(str) + 1);
1378 sprintf(new_str, "%s%s", old_str, str);
1379 fvalue_set(&fi->value, new_str, TRUE);
1382 /* Set the FT_STRING value */
1384 proto_tree_set_string(field_info *fi, const char* value,
1385 gboolean already_allocated)
1387 fvalue_set(&fi->value, (gpointer) value, already_allocated);
1391 proto_tree_set_string_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
1396 length = tvb_ensure_length_remaining(tvb, start);
1399 /* This memory is freed in proto_tree_free_node() */
1400 string = tvb_get_string(tvb, start, length);
1401 proto_tree_set_string(fi, string, TRUE);
1404 /* Add a FT_ETHER to a proto_tree */
1406 proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1407 const guint8* value)
1411 header_field_info *hfinfo;
1416 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
1417 g_assert(hfinfo->type == FT_ETHER);
1419 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
1420 proto_tree_set_ether(new_fi, value);
1426 proto_tree_add_ether_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1427 const guint8* value)
1431 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
1435 PROTO_ITEM_SET_HIDDEN(pi);
1441 proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1442 const guint8* value, const char *format, ...)
1447 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
1451 va_start(ap, format);
1452 proto_tree_set_representation(pi, format, ap);
1458 /* Set the FT_ETHER value */
1460 proto_tree_set_ether(field_info *fi, const guint8* value)
1462 fvalue_set(&fi->value, (gpointer) value, FALSE);
1466 proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, gint start)
1468 proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, 6));
1471 /* Add a FT_BOOLEAN to a proto_tree */
1473 proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1478 header_field_info *hfinfo;
1483 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
1484 g_assert(hfinfo->type == FT_BOOLEAN);
1486 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
1487 proto_tree_set_boolean(new_fi, value);
1493 proto_tree_add_boolean_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1498 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
1502 PROTO_ITEM_SET_HIDDEN(pi);
1508 proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1509 guint32 value, const char *format, ...)
1514 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
1518 va_start(ap, format);
1519 proto_tree_set_representation(pi, format, ap);
1525 /* Set the FT_BOOLEAN value */
1527 proto_tree_set_boolean(field_info *fi, guint32 value)
1529 proto_tree_set_uint(fi, value);
1532 /* Add a FT_FLOAT to a proto_tree */
1534 proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1539 header_field_info *hfinfo;
1544 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
1545 g_assert(hfinfo->type == FT_FLOAT);
1547 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
1548 proto_tree_set_float(new_fi, value);
1554 proto_tree_add_float_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1559 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
1563 PROTO_ITEM_SET_HIDDEN(pi);
1569 proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1570 float value, const char *format, ...)
1575 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
1579 va_start(ap, format);
1580 proto_tree_set_representation(pi, format, ap);
1586 /* Set the FT_FLOAT value */
1588 proto_tree_set_float(field_info *fi, float value)
1590 fvalue_set_floating(&fi->value, value);
1593 /* Add a FT_DOUBLE to a proto_tree */
1595 proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1600 header_field_info *hfinfo;
1605 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
1606 g_assert(hfinfo->type == FT_DOUBLE);
1608 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
1609 proto_tree_set_double(new_fi, value);
1615 proto_tree_add_double_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1620 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
1624 PROTO_ITEM_SET_HIDDEN(pi);
1630 proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1631 double value, const char *format, ...)
1636 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
1640 va_start(ap, format);
1641 proto_tree_set_representation(pi, format, ap);
1647 /* Set the FT_DOUBLE value */
1649 proto_tree_set_double(field_info *fi, double value)
1651 fvalue_set_floating(&fi->value, value);
1654 /* Add FT_UINT{8,16,24,32} to a proto_tree */
1656 proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1659 proto_item *pi = NULL;
1661 header_field_info *hfinfo;
1666 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
1667 switch(hfinfo->type) {
1673 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length,
1675 proto_tree_set_uint(new_fi, value);
1679 g_assert_not_reached();
1686 proto_tree_add_uint_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1691 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
1695 PROTO_ITEM_SET_HIDDEN(pi);
1701 proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1702 guint32 value, const char *format, ...)
1707 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
1711 va_start(ap, format);
1712 proto_tree_set_representation(pi, format, ap);
1718 /* Set the FT_UINT{8,16,24,32} value */
1720 proto_tree_set_uint(field_info *fi, guint32 value)
1722 header_field_info *hfinfo;
1725 hfinfo = fi->hfinfo;
1728 if (hfinfo->bitmask) {
1729 /* Mask out irrelevant portions */
1730 integer &= hfinfo->bitmask;
1733 if (hfinfo->bitshift > 0) {
1734 integer >>= hfinfo->bitshift;
1737 fvalue_set_integer(&fi->value, integer);
1740 /* Add FT_UINT64 to a proto_tree */
1742 proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1745 proto_item *pi = NULL;
1747 header_field_info *hfinfo;
1752 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
1753 g_assert(hfinfo->type == FT_UINT64);
1755 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
1756 proto_tree_set_uint64(new_fi, value);
1762 proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1763 guint64 value, const char *format, ...)
1768 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
1772 va_start(ap, format);
1773 proto_tree_set_representation(pi, format, ap);
1779 /* Add FT_INT{8,16,24,32} to a proto_tree */
1781 proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1784 proto_item *pi = NULL;
1786 header_field_info *hfinfo;
1791 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
1792 switch(hfinfo->type) {
1797 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length,
1799 proto_tree_set_int(new_fi, value);
1803 g_assert_not_reached();
1810 proto_tree_add_int_hidden(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1815 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
1819 PROTO_ITEM_SET_HIDDEN(pi);
1825 proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1826 gint32 value, const char *format, ...)
1828 proto_item *pi = NULL;
1831 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
1835 va_start(ap, format);
1836 proto_tree_set_representation(pi, format, ap);
1842 /* Set the FT_INT{8,16,24,32} value */
1844 proto_tree_set_int(field_info *fi, gint32 value)
1846 header_field_info *hfinfo;
1849 hfinfo = fi->hfinfo;
1850 integer = (guint32) value;
1852 if (hfinfo->bitmask) {
1853 /* Mask out irrelevant portions */
1854 integer &= hfinfo->bitmask;
1857 if (hfinfo->bitshift > 0) {
1858 integer >>= hfinfo->bitshift;
1861 fvalue_set_integer(&fi->value, integer);
1864 /* Add FT_INT64 to a proto_tree */
1866 proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1869 proto_item *pi = NULL;
1871 header_field_info *hfinfo;
1876 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
1877 g_assert(hfinfo->type == FT_INT64);
1879 pi = proto_tree_add_pi(tree, hfindex, tvb, start, &length, &new_fi);
1880 proto_tree_set_uint64(new_fi, (guint64)value);
1886 proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
1887 gint64 value, const char *format, ...)
1892 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
1896 va_start(ap, format);
1897 proto_tree_set_representation(pi, format, ap);
1904 /* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
1906 proto_tree_add_node(proto_tree *tree, field_info *fi)
1908 proto_node *pnode, *tnode, *sibling;
1912 * Make sure "tree" is ready to have subtrees under it, by
1913 * checking whether it's been given an ett_ value.
1915 * "tnode->finfo" may be null; that's the case for the root
1916 * node of the protocol tree. That node is not displayed,
1917 * so it doesn't need an ett_ value to remember whether it
1922 g_assert(tfi == NULL ||
1923 (tfi->tree_type >= 0 && tfi->tree_type < num_tree_types));
1925 PROTO_NODE_NEW(pnode);
1926 pnode->parent = tnode;
1928 pnode->tree_data = PTREE_DATA(tree);
1930 if (tnode->last_child != NULL) {
1931 sibling = tnode->last_child;
1932 g_assert(sibling->next == NULL);
1933 sibling->next = pnode;
1935 tnode->first_child = pnode;
1936 tnode->last_child = pnode;
1938 return (proto_item*)pnode;
1942 /* Generic way to allocate field_info and add to proto_tree.
1943 * Sets *pfi to address of newly-allocated field_info struct, if pfi is
1946 proto_tree_add_pi(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
1947 gint *length, field_info **pfi)
1957 fi = alloc_field_info(tree, hfindex, tvb, start, length);
1958 pi = proto_tree_add_node(tree, fi);
1960 /* If the proto_tree wants to keep a record of this finfo
1961 * for quick lookup, then record it. */
1962 hash = PTREE_DATA(tree)->interesting_hfids;
1963 ptrs = g_hash_table_lookup(hash, GINT_TO_POINTER(hfindex));
1965 g_ptr_array_add(ptrs, fi);
1968 /* Does the caller want to know the fi pointer? */
1977 alloc_field_info(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start,
1980 header_field_info *hfinfo;
1984 * We only allow a null tvbuff if the item has a zero length,
1985 * i.e. if there's no data backing it.
1987 g_assert(tvb != NULL || *length == 0);
1989 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
1991 if (*length == -1) {
1993 * For FT_NONE, FT_PROTOCOL, FT_BYTES, and FT_STRING fields,
1994 * a length of -1 means "set the length to what remains in
1997 * The assumption is either that
1999 * 1) the length of the item can only be determined
2000 * by dissection (typically true of items with
2001 * subitems, which are probably FT_NONE or
2006 * 2) if the tvbuff is "short" (either due to a short
2007 * snapshot length or due to lack of reassembly of
2008 * fragments/segments/whatever), we want to display
2009 * what's available in the field (probably FT_BYTES
2010 * or FT_STRING) and then throw an exception later
2014 * 3) the field is defined to be "what's left in the
2017 * so we set the length to what remains in the tvbuff so
2018 * that, if we throw an exception while dissecting, it
2019 * has what is probably the right value.
2021 * For FT_STRINGZ, it means "the string is null-terminated,
2022 * not null-padded; set the length to the actual length
2023 * of the string", and if the tvbuff if short, we just
2024 * throw an exception.
2026 * It's not valid for any other type of field.
2028 switch (hfinfo->type) {
2032 * We allow this to be zero-length - for
2033 * example, an ONC RPC NULL procedure has
2034 * neither arguments nor reply, so the
2035 * payload for that protocol is empty.
2037 * However, if the length is negative, the
2038 * start offset is *past* the byte past the
2039 * end of the tvbuff, so we throw an
2042 *length = tvb_length_remaining(tvb, start);
2045 * Use "tvb_ensure_bytes_exist()"
2046 * to force the appropriate exception
2049 tvb_ensure_bytes_exist(tvb, start, 0);
2051 g_assert(*length >= 0);
2057 *length = tvb_ensure_length_remaining(tvb, start);
2058 g_assert(*length >= 0);
2063 * Leave the length as -1, so our caller knows
2069 g_assert_not_reached();
2072 g_assert(*length >= 0);
2076 fi->hfinfo = hfinfo;
2078 fi->start+=(tvb)?TVB_RAW_OFFSET(tvb):0;
2079 fi->length = *length;
2082 if (!PTREE_DATA(tree)->visible)
2083 FI_SET_FLAG(fi, FI_HIDDEN);
2084 fvalue_init(&fi->value, fi->hfinfo->type);
2087 /* add the data source tvbuff */
2088 fi->ds_tvb=tvb?TVB_GET_DS_TVB(tvb):NULL;
2093 /* Set representation of a proto_tree entry, if the protocol tree is to
2096 proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
2098 int ret; /*tmp return value */
2099 field_info *fi = PITEM_FINFO(pi);
2101 if (!PROTO_ITEM_IS_HIDDEN(pi)) {
2102 ITEM_LABEL_NEW(fi->rep);
2103 ret = vsnprintf(fi->rep->representation, ITEM_LABEL_LENGTH, format, ap);
2104 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
2105 fi->rep->representation[ITEM_LABEL_LENGTH - 1] = '\0';
2109 /* Set text of proto_item after having already been created. */
2111 proto_item_set_text(proto_item *pi, const char *format, ...)
2113 field_info *fi = NULL;
2120 fi = PITEM_FINFO(pi);
2123 ITEM_LABEL_FREE(fi->rep);
2126 va_start(ap, format);
2127 proto_tree_set_representation(pi, format, ap);
2131 /* Append to text of proto_item after having already been created. */
2133 proto_item_append_text(proto_item *pi, const char *format, ...)
2135 field_info *fi = NULL;
2138 int ret; /*tmp return value */
2144 fi = PITEM_FINFO(pi);
2146 if (!PROTO_ITEM_IS_HIDDEN(pi)) {
2147 va_start(ap, format);
2150 * If we don't already have a representation,
2151 * generate the default representation.
2153 if (fi->rep == NULL) {
2154 ITEM_LABEL_NEW(fi->rep);
2155 proto_item_fill_label(fi, fi->rep->representation);
2158 curlen = strlen(fi->rep->representation);
2159 if (ITEM_LABEL_LENGTH > curlen) {
2160 ret = vsnprintf(fi->rep->representation + curlen,
2161 ITEM_LABEL_LENGTH - curlen, format, ap);
2162 if ((ret == -1) || (ret >= (int)(ITEM_LABEL_LENGTH - curlen)))
2163 fi->rep->representation[ITEM_LABEL_LENGTH - 1] = '\0';
2170 proto_item_set_len(proto_item *pi, gint length)
2176 fi = PITEM_FINFO(pi);
2177 g_assert(length >= 0);
2178 fi->length = length;
2182 * Sets the length of the item based on its start and on the specified
2183 * offset, which is the offset past the end of the item; as the start
2184 * in the item is relative to the beginning of the data source tvbuff,
2185 * we need to pass in a tvbuff - the end offset is relative to the beginning
2189 proto_item_set_end(proto_item *pi, tvbuff_t *tvb, gint end)
2195 fi = PITEM_FINFO(pi);
2196 end += TVB_RAW_OFFSET(tvb);
2197 g_assert(end >= fi->start);
2198 fi->length = end - fi->start;
2202 proto_item_get_len(proto_item *pi)
2204 field_info *fi = PITEM_FINFO(pi);
2209 proto_tree_create_root(void)
2213 /* Initialize the proto_node */
2214 PROTO_NODE_NEW(pnode);
2215 pnode->parent = NULL;
2216 pnode->finfo = NULL;
2217 pnode->tree_data = g_new(tree_data_t, 1);
2219 /* Initialize the tree_data_t */
2220 pnode->tree_data->interesting_hfids =
2221 g_hash_table_new(g_direct_hash, g_direct_equal);
2223 /* Set the default to FALSE so it's easier to
2224 * find errors; if we expect to see the protocol tree
2225 * but for some reason the default 'visible' is not
2226 * changed, then we'll find out very quickly. */
2227 pnode->tree_data->visible = FALSE;
2229 return (proto_tree*) pnode;
2233 /* "prime" a proto_tree with a single hfid that a dfilter
2234 * is interested in. */
2236 proto_tree_prime_hfid(proto_tree *tree, gint hfid)
2238 g_hash_table_insert(PTREE_DATA(tree)->interesting_hfids,
2239 GINT_TO_POINTER(hfid), g_ptr_array_new());
2244 proto_item_add_subtree(proto_item *pi, gint idx) {
2250 fi = PITEM_FINFO(pi);
2251 g_assert(idx >= 0 && idx < num_tree_types);
2252 fi->tree_type = idx;
2253 return (proto_tree*) pi;
2257 proto_item_get_subtree(proto_item *pi) {
2262 fi = PITEM_FINFO(pi);
2263 if (fi->tree_type == -1)
2265 return (proto_tree*) pi;
2269 proto_item_get_parent(proto_item *ti) {
2276 proto_item_get_parent_nth(proto_item *ti, int gen) {
2289 proto_tree_get_parent(proto_tree *tree) {
2292 return (proto_item*) tree;
2296 proto_match_short_name(gconstpointer p_arg, gconstpointer name_arg)
2298 const protocol_t *p = p_arg;
2299 const char *name = name_arg;
2301 return g_strcasecmp(p->short_name, name);
2305 proto_match_name(gconstpointer p_arg, gconstpointer name_arg)
2307 const protocol_t *p = p_arg;
2308 const char *name = name_arg;
2310 return g_strcasecmp(p->name, name);
2314 proto_match_filter_name(gconstpointer p_arg, gconstpointer name_arg)
2316 const protocol_t *p = p_arg;
2317 const char *name = name_arg;
2319 return g_strcasecmp(p->filter_name, name);
2323 proto_compare_name(gconstpointer p1_arg, gconstpointer p2_arg)
2325 const protocol_t *p1 = p1_arg;
2326 const protocol_t *p2 = p2_arg;
2328 return g_strcasecmp(p1->short_name, p2->short_name);
2332 proto_register_protocol(char *name, char *short_name, char *filter_name)
2334 protocol_t *protocol;
2335 header_field_info *hfinfo;
2339 * Make sure there's not already a protocol with any of those
2340 * names. Crash if there is, as that's an error in the code,
2341 * and the code has to be fixed not to register more than one
2342 * protocol with the same name.
2344 g_assert(g_list_find_custom(protocols, name, proto_match_name) == NULL);
2345 g_assert(g_list_find_custom(protocols, short_name, proto_match_short_name) == NULL);
2346 g_assert(g_list_find_custom(protocols, filter_name, proto_match_filter_name) == NULL);
2348 /* Add this protocol to the list of known protocols; the list
2349 is sorted by protocol short name. */
2350 protocol = g_malloc(sizeof (protocol_t));
2351 protocol->name = name;
2352 protocol->short_name = short_name;
2353 protocol->filter_name = filter_name;
2354 protocol->fields = NULL;
2355 protocol->is_enabled = TRUE; /* protocol is enabled by default */
2356 protocol->can_toggle = TRUE;
2357 protocols = g_list_insert_sorted(protocols, protocol,
2358 proto_compare_name);
2360 /* Here we do allocate a new header_field_info struct */
2361 hfinfo = g_mem_chunk_alloc(gmc_hfinfo);
2362 hfinfo->name = name;
2363 hfinfo->abbrev = filter_name;
2364 hfinfo->type = FT_PROTOCOL;
2365 hfinfo->strings = NULL;
2366 hfinfo->bitmask = 0;
2367 hfinfo->bitshift = 0;
2369 hfinfo->parent = -1; /* this field differentiates protos and fields */
2371 proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
2372 protocol->proto_id = proto_id;
2377 * Routines to use to iterate over the protocols.
2378 * The argument passed to the iterator routines is an opaque cookie to
2379 * their callers; it's the GList pointer for the current element in
2381 * The ID of the protocol is returned, or -1 if there is no protocol.
2384 proto_get_first_protocol(void **cookie)
2386 protocol_t *protocol;
2388 if (protocols == NULL)
2390 *cookie = protocols;
2391 protocol = protocols->data;
2392 return protocol->proto_id;
2396 proto_get_next_protocol(void **cookie)
2398 GList *list_item = *cookie;
2399 protocol_t *protocol;
2401 list_item = g_list_next(list_item);
2402 if (list_item == NULL)
2404 *cookie = list_item;
2405 protocol = list_item->data;
2406 return protocol->proto_id;
2410 proto_get_first_protocol_field(int proto_id, void **cookie)
2412 protocol_t *protocol = find_protocol_by_id(proto_id);
2413 hf_register_info *ptr;
2415 if ((protocol == NULL) || (protocol->fields == NULL))
2418 *cookie = protocol->fields;
2419 ptr = protocol->fields->data;
2420 return &ptr->hfinfo;
2424 proto_get_next_protocol_field(void **cookie)
2426 GList *list_item = *cookie;
2427 hf_register_info *ptr;
2429 list_item = g_list_next(list_item);
2430 if (list_item == NULL)
2433 *cookie = list_item;
2434 ptr = list_item->data;
2435 return &ptr->hfinfo;
2439 * Find the protocol list entry for a protocol given its field ID.
2442 compare_proto_id(gconstpointer proto_arg, gconstpointer id_arg)
2444 const protocol_t *protocol = proto_arg;
2445 const int *id_ptr = id_arg;
2447 return (protocol->proto_id == *id_ptr) ? 0 : 1;
2451 find_protocol_by_id(int proto_id)
2455 list_entry = g_list_find_custom(protocols, &proto_id, compare_proto_id);
2456 if (list_entry == NULL)
2458 return list_entry->data;
2461 static gint compare_filter_name(gconstpointer proto_arg,
2462 gconstpointer filter_name)
2464 const protocol_t *protocol = proto_arg;
2465 const gchar* f_name = filter_name;
2467 return (strcmp(protocol->filter_name, f_name));
2471 proto_get_id(protocol_t *protocol)
2473 return protocol->proto_id;
2476 int proto_get_id_by_filter_name(gchar* filter_name)
2479 protocol_t *protocol;
2481 list_entry = g_list_find_custom(protocols, filter_name,
2482 compare_filter_name);
2483 if (list_entry == NULL)
2485 protocol = list_entry->data;
2486 return protocol->proto_id;
2490 proto_get_protocol_name(int proto_id)
2492 protocol_t *protocol;
2494 protocol = find_protocol_by_id(proto_id);
2495 return protocol->name;
2499 proto_get_protocol_short_name(protocol_t *protocol)
2501 if (protocol == NULL)
2503 return protocol->short_name;
2507 proto_get_protocol_filter_name(int proto_id)
2509 protocol_t *protocol;
2511 protocol = find_protocol_by_id(proto_id);
2512 return protocol->filter_name;
2516 proto_is_protocol_enabled(protocol_t *protocol)
2518 return protocol->is_enabled;
2522 proto_can_toggle_protocol(int proto_id)
2524 protocol_t *protocol;
2526 protocol = find_protocol_by_id(proto_id);
2527 return protocol->can_toggle;
2531 proto_set_decoding(int proto_id, gboolean enabled)
2533 protocol_t *protocol;
2535 protocol = find_protocol_by_id(proto_id);
2536 g_assert(protocol->can_toggle);
2537 protocol->is_enabled = enabled;
2541 proto_set_cant_toggle(int proto_id)
2543 protocol_t *protocol;
2545 protocol = find_protocol_by_id(proto_id);
2546 protocol->can_toggle = FALSE;
2549 /* for use with static arrays only, since we don't allocate our own copies
2550 of the header_field_info struct contained within the hf_register_info struct */
2552 proto_register_field_array(int parent, hf_register_info *hf, int num_records)
2555 hf_register_info *ptr = hf;
2558 proto = find_protocol_by_id(parent);
2559 for (i = 0; i < num_records; i++, ptr++) {
2561 * Make sure we haven't registered this yet.
2562 * Most fields have variables associated with them
2563 * that are initialized to -1; some have array elements,
2564 * or possibly uninitialized variables, so we also allow
2565 * 0 (which is unlikely to be the field ID we get back
2566 * from "proto_register_field_init()").
2568 g_assert(*ptr->p_id == -1 || *ptr->p_id == 0);
2570 if (proto != NULL) {
2571 if (proto->fields == NULL) {
2572 proto->fields = g_list_append(NULL, ptr);
2573 proto->last_field = proto->fields;
2576 g_list_append(proto->last_field, ptr)->next;
2579 field_id = proto_register_field_init(&ptr->hfinfo, parent);
2580 *ptr->p_id = field_id;
2585 proto_register_field_init(header_field_info *hfinfo, int parent)
2587 /* The field must have names */
2588 g_assert(hfinfo->name);
2589 g_assert(hfinfo->abbrev);
2591 /* These types of fields are allowed to have value_strings or true_false_strings */
2592 g_assert((hfinfo->strings == NULL) || (
2593 (hfinfo->type == FT_UINT8) ||
2594 (hfinfo->type == FT_UINT16) ||
2595 (hfinfo->type == FT_UINT24) ||
2596 (hfinfo->type == FT_UINT32) ||
2597 (hfinfo->type == FT_INT8) ||
2598 (hfinfo->type == FT_INT16) ||
2599 (hfinfo->type == FT_INT24) ||
2600 (hfinfo->type == FT_INT32) ||
2601 (hfinfo->type == FT_BOOLEAN) ||
2602 (hfinfo->type == FT_FRAMENUM) ));
2604 switch (hfinfo->type) {
2614 /* Require integral types (other than frame number, which is
2615 always displayed in decimal) to have a number base */
2616 g_assert(hfinfo->display != BASE_NONE);
2620 /* Don't allow bitfields or value strings for frame numbers */
2621 g_assert(hfinfo->bitmask == 0);
2622 g_assert(hfinfo->strings == NULL);
2628 /* if this is a bitfield, compute bitshift */
2629 if (hfinfo->bitmask) {
2630 while ((hfinfo->bitmask & (1 << hfinfo->bitshift)) == 0)
2634 hfinfo->parent = parent;
2635 hfinfo->same_name_next = NULL;
2636 hfinfo->same_name_prev = NULL;
2638 /* if we always add and never delete, then id == len - 1 is correct */
2639 if(gpa_hfinfo.len>=gpa_hfinfo.allocated_len){
2640 if(!gpa_hfinfo.hfi){
2641 gpa_hfinfo.allocated_len=1000;
2642 gpa_hfinfo.hfi=g_malloc(sizeof(header_field_info *)*1000);
2644 gpa_hfinfo.allocated_len+=1000;
2645 gpa_hfinfo.hfi=g_realloc(gpa_hfinfo.hfi, sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
2648 gpa_hfinfo.hfi[gpa_hfinfo.len]=hfinfo;
2650 hfinfo->id = gpa_hfinfo.len - 1;
2652 /* if we have real names, enter this field in the name tree */
2653 if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) {
2655 header_field_info *same_name_hfinfo, *same_name_next_hfinfo;
2659 /* Check that the filter name (abbreviation) is legal;
2660 * it must contain only alphanumerics, '-', "_", and ".". */
2661 for (p = hfinfo->abbrev; (c = *p) != '\0'; p++)
2662 g_assert(isalnum(c) || c == '-' || c == '_' ||
2665 /* We allow multiple hfinfo's to be registered under the same
2666 * abbreviation. This was done for X.25, as, depending
2667 * on whether it's modulo-8 or modulo-128 operation,
2668 * some bitfield fields may be in different bits of
2669 * a byte, and we want to be able to refer to that field
2670 * with one name regardless of whether the packets
2671 * are modulo-8 or modulo-128 packets. */
2672 same_name_hfinfo = g_tree_lookup(gpa_name_tree, hfinfo->abbrev);
2673 if (same_name_hfinfo) {
2674 /* There's already a field with this name.
2675 * Put it after that field in the list of
2676 * fields with this name, then allow the code
2677 * after this if{} block to replace the old
2678 * hfinfo with the new hfinfo in the GTree. Thus,
2679 * we end up with a linked-list of same-named hfinfo's,
2680 * with the root of the list being the hfinfo in the GTree */
2681 same_name_next_hfinfo =
2682 same_name_hfinfo->same_name_next;
2684 hfinfo->same_name_next = same_name_next_hfinfo;
2685 if (same_name_next_hfinfo)
2686 same_name_next_hfinfo->same_name_prev = hfinfo;
2688 same_name_hfinfo->same_name_next = hfinfo;
2689 hfinfo->same_name_prev = same_name_hfinfo;
2691 g_tree_insert(gpa_name_tree, hfinfo->abbrev, hfinfo);
2698 proto_register_subtree_array(gint **indices, int num_indices)
2701 gint **ptr = indices;
2704 * Make sure we haven't already allocated the array of "tree is
2707 * XXX - if it's *really* important to allow more ett_ values to
2708 * be given out after "proto_init()" is called, we could expand
2711 g_assert(tree_is_expanded == NULL);
2714 * Assign "num_indices" subtree numbers starting at "num_tree_types",
2715 * returning the indices through the pointers in the array whose
2716 * first element is pointed to by "indices", and update
2717 * "num_tree_types" appropriately.
2719 for (i = 0; i < num_indices; i++, ptr++, num_tree_types++)
2720 **ptr = num_tree_types;
2724 proto_item_fill_label(field_info *fi, gchar *label_str)
2726 header_field_info *hfinfo = fi->hfinfo;
2731 guint32 n_addr; /* network-order IPv4 address */
2732 int ret; /*tmp return value */
2734 switch(hfinfo->type) {
2737 ret = snprintf(label_str, ITEM_LABEL_LENGTH,
2738 "%s", hfinfo->name);
2739 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
2740 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
2744 fill_label_boolean(fi, label_str);
2749 bytes = fvalue_get(&fi->value);
2751 ret = snprintf(label_str, ITEM_LABEL_LENGTH,
2752 "%s: %s", hfinfo->name,
2753 bytes_to_str(bytes, fvalue_length(&fi->value)));
2754 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
2755 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
2758 ret = snprintf(label_str, ITEM_LABEL_LENGTH,
2759 "%s: <MISSING>", hfinfo->name);
2760 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
2761 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
2765 /* Four types of integers to take care of:
2766 * Bitfield, with val_string
2767 * Bitfield, w/o val_string
2768 * Non-bitfield, with val_string
2769 * Non-bitfield, w/o val_string
2776 if (hfinfo->bitmask) {
2777 if (hfinfo->strings) {
2778 fill_label_enumerated_bitfield(fi, label_str);
2781 fill_label_numeric_bitfield(fi, label_str);
2785 if (hfinfo->strings) {
2786 fill_label_enumerated_uint(fi, label_str);
2789 fill_label_uint(fi, label_str);
2795 fill_label_uint64(fi, label_str);
2802 g_assert(!hfinfo->bitmask);
2803 if (hfinfo->strings) {
2804 fill_label_enumerated_int(fi, label_str);
2807 fill_label_int(fi, label_str);
2812 fill_label_int64(fi, label_str);
2816 ret = snprintf(label_str, ITEM_LABEL_LENGTH,
2817 "%s: %." STRINGIFY(FLT_DIG) "f",
2818 hfinfo->name, fvalue_get_floating(&fi->value));
2819 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
2820 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
2824 ret = snprintf(label_str, ITEM_LABEL_LENGTH,
2825 "%s: %." STRINGIFY(DBL_DIG) "g",
2826 hfinfo->name, fvalue_get_floating(&fi->value));
2827 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
2828 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
2831 case FT_ABSOLUTE_TIME:
2832 ret = snprintf(label_str, ITEM_LABEL_LENGTH,
2833 "%s: %s", hfinfo->name,
2834 abs_time_to_str(fvalue_get(&fi->value)));
2835 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
2836 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
2839 case FT_RELATIVE_TIME:
2840 ret = snprintf(label_str, ITEM_LABEL_LENGTH,
2841 "%s: %s seconds", hfinfo->name,
2842 rel_time_to_secs_str(fvalue_get(&fi->value)));
2843 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
2844 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
2848 integer = fvalue_get_integer(&fi->value);
2849 ret = snprintf(label_str, ITEM_LABEL_LENGTH,
2850 "%s: 0x%08X (%s)", hfinfo->name,
2851 integer, get_ipxnet_name(integer));
2852 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
2853 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
2857 bytes = fvalue_get(&fi->value);
2858 ret = snprintf(label_str, ITEM_LABEL_LENGTH,
2859 "%s: %s (%s)", hfinfo->name,
2860 ether_to_str(bytes),
2861 get_ether_name(bytes));
2862 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
2863 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
2867 ipv4 = fvalue_get(&fi->value);
2868 n_addr = ipv4_get_net_order_addr(ipv4);
2869 ret = snprintf(label_str, ITEM_LABEL_LENGTH,
2870 "%s: %s (%s)", hfinfo->name,
2871 get_hostname(n_addr),
2872 ip_to_str((guint8*)&n_addr));
2873 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
2874 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
2878 bytes = fvalue_get(&fi->value);
2879 ret = snprintf(label_str, ITEM_LABEL_LENGTH,
2880 "%s: %s (%s)", hfinfo->name,
2881 get_hostname6((struct e_in6_addr *)bytes),
2882 ip6_to_str((struct e_in6_addr*)bytes));
2883 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
2884 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
2889 case FT_UINT_STRING:
2890 bytes = fvalue_get(&fi->value);
2891 ret = snprintf(label_str, ITEM_LABEL_LENGTH,
2892 "%s: %s", hfinfo->name,
2893 format_text(bytes, strlen(bytes)));
2894 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
2895 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
2899 g_error("hfinfo->type %d (%s) not handled\n",
2901 ftype_name(hfinfo->type));
2902 g_assert_not_reached();
2908 fill_label_boolean(field_info *fi, gchar *label_str)
2910 char *p = label_str;
2911 int bitfield_byte_length = 0, bitwidth;
2912 guint32 unshifted_value;
2914 int ret; /*tmp return value */
2916 header_field_info *hfinfo = fi->hfinfo;
2917 static const true_false_string default_tf = { "True", "False" };
2918 const true_false_string *tfstring = &default_tf;
2920 if (hfinfo->strings) {
2921 tfstring = (const struct true_false_string*) hfinfo->strings;
2924 value = fvalue_get_integer(&fi->value);
2925 if (hfinfo->bitmask) {
2926 /* Figure out the bit width */
2927 bitwidth = hfinfo_bitwidth(hfinfo);
2930 unshifted_value = value;
2931 if (hfinfo->bitshift > 0) {
2932 unshifted_value <<= hfinfo->bitshift;
2935 /* Create the bitfield first */
2936 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
2937 bitfield_byte_length = p - label_str;
2940 /* Fill in the textual info */
2941 ret = snprintf(p, ITEM_LABEL_LENGTH - bitfield_byte_length,
2942 "%s: %s", hfinfo->name,
2943 value ? tfstring->true_string : tfstring->false_string);
2944 if ((ret == -1) || (ret >= (ITEM_LABEL_LENGTH - bitfield_byte_length)))
2945 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
2949 /* Fills data for bitfield ints with val_strings */
2951 fill_label_enumerated_bitfield(field_info *fi, gchar *label_str)
2953 char *format = NULL, *p;
2954 int bitfield_byte_length, bitwidth;
2955 guint32 unshifted_value;
2957 int ret; /*tmp return value */
2959 header_field_info *hfinfo = fi->hfinfo;
2961 /* Figure out the bit width */
2962 bitwidth = hfinfo_bitwidth(hfinfo);
2964 /* Pick the proper format string */
2965 format = hfinfo_uint_vals_format(hfinfo);
2968 unshifted_value = fvalue_get_integer(&fi->value);
2969 value = unshifted_value;
2970 if (hfinfo->bitshift > 0) {
2971 unshifted_value <<= hfinfo->bitshift;
2974 /* Create the bitfield first */
2975 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
2976 bitfield_byte_length = p - label_str;
2978 /* Fill in the textual info using stored (shifted) value */
2979 ret = snprintf(p, ITEM_LABEL_LENGTH - bitfield_byte_length,
2980 format, hfinfo->name,
2981 val_to_str(value, cVALS(hfinfo->strings), "Unknown"), value);
2982 if ((ret == -1) || (ret >= (ITEM_LABEL_LENGTH - bitfield_byte_length)))
2983 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
2987 fill_label_numeric_bitfield(field_info *fi, gchar *label_str)
2989 char *format = NULL, *p;
2990 int bitfield_byte_length, bitwidth;
2991 guint32 unshifted_value;
2993 int ret; /*tmp return value */
2995 header_field_info *hfinfo = fi->hfinfo;
2997 /* Figure out the bit width */
2998 bitwidth = hfinfo_bitwidth(hfinfo);
3000 /* Pick the proper format string */
3001 format = hfinfo_uint_format(hfinfo);
3004 unshifted_value = fvalue_get_integer(&fi->value);
3005 value = unshifted_value;
3006 if (hfinfo->bitshift > 0) {
3007 unshifted_value <<= hfinfo->bitshift;
3010 /* Create the bitfield using */
3011 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
3012 bitfield_byte_length = p - label_str;
3014 /* Fill in the textual info using stored (shifted) value */
3015 ret = snprintf(p, ITEM_LABEL_LENGTH - bitfield_byte_length,
3016 format, hfinfo->name, value);
3017 if ((ret == -1) || (ret >= (ITEM_LABEL_LENGTH - bitfield_byte_length)))
3018 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
3023 fill_label_enumerated_uint(field_info *fi, gchar *label_str)
3025 char *format = NULL;
3026 header_field_info *hfinfo = fi->hfinfo;
3028 int ret; /*tmp return value */
3030 /* Pick the proper format string */
3031 format = hfinfo_uint_vals_format(hfinfo);
3033 value = fvalue_get_integer(&fi->value);
3035 /* Fill in the textual info */
3036 ret = snprintf(label_str, ITEM_LABEL_LENGTH,
3037 format, hfinfo->name,
3038 val_to_str(value, cVALS(hfinfo->strings), "Unknown"), value);
3039 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
3040 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
3044 fill_label_uint(field_info *fi, gchar *label_str)
3046 char *format = NULL;
3047 header_field_info *hfinfo = fi->hfinfo;
3049 int ret; /*tmp return value */
3051 /* Pick the proper format string */
3052 format = hfinfo_uint_format(hfinfo);
3053 value = fvalue_get_integer(&fi->value);
3055 /* Fill in the textual info */
3056 ret = snprintf(label_str, ITEM_LABEL_LENGTH,
3057 format, hfinfo->name, value);
3058 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
3059 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
3063 fill_label_uint64(field_info *fi, gchar *label_str)
3065 char *format = NULL;
3066 header_field_info *hfinfo = fi->hfinfo;
3068 int ret; /*tmp return value */
3070 /* Pick the proper format string */
3071 format = hfinfo_uint64_format(hfinfo);
3072 value = fvalue_get_integer64(&fi->value);
3074 /* Fill in the textual info */
3075 ret = snprintf(label_str, ITEM_LABEL_LENGTH,
3076 format, hfinfo->name, value);
3077 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
3078 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
3082 fill_label_enumerated_int(field_info *fi, gchar *label_str)
3084 char *format = NULL;
3085 header_field_info *hfinfo = fi->hfinfo;
3087 int ret; /*tmp return value */
3089 /* Pick the proper format string */
3090 format = hfinfo_int_vals_format(hfinfo);
3091 value = fvalue_get_integer(&fi->value);
3093 /* Fill in the textual info */
3094 ret = snprintf(label_str, ITEM_LABEL_LENGTH,
3095 format, hfinfo->name,
3096 val_to_str(value, cVALS(hfinfo->strings), "Unknown"), value);
3097 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
3098 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
3102 fill_label_int(field_info *fi, gchar *label_str)
3104 char *format = NULL;
3105 header_field_info *hfinfo = fi->hfinfo;
3107 int ret; /*tmp return value */
3109 /* Pick the proper format string */
3110 format = hfinfo_int_format(hfinfo);
3111 value = fvalue_get_integer(&fi->value);
3113 /* Fill in the textual info */
3114 ret = snprintf(label_str, ITEM_LABEL_LENGTH,
3115 format, hfinfo->name, value);
3116 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
3117 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
3121 fill_label_int64(field_info *fi, gchar *label_str)
3123 char *format = NULL;
3124 header_field_info *hfinfo = fi->hfinfo;
3126 int ret; /*tmp return value */
3128 /* Pick the proper format string */
3129 format = hfinfo_int64_format(hfinfo);
3130 value = fvalue_get_integer64(&fi->value);
3132 /* Fill in the textual info */
3133 ret = snprintf(label_str, ITEM_LABEL_LENGTH,
3134 format, hfinfo->name, value);
3135 if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
3136 label_str[ITEM_LABEL_LENGTH - 1] = '\0';
3140 hfinfo_bitwidth(header_field_info *hfinfo)
3144 if (!hfinfo->bitmask) {
3148 switch(hfinfo->type) {
3166 bitwidth = hfinfo->display; /* hacky? :) */
3169 g_assert_not_reached();
3176 hfinfo_uint_vals_format(header_field_info *hfinfo)
3178 char *format = NULL;
3180 switch(hfinfo->display) {
3182 format = "%s: %s (%u)";
3184 case BASE_OCT: /* I'm lazy */
3185 format = "%s: %s (%o)";
3188 switch(hfinfo->type) {
3190 format = "%s: %s (0x%02x)";
3193 format = "%s: %s (0x%04x)";
3196 format = "%s: %s (0x%06x)";
3199 format = "%s: %s (0x%08x)";
3202 g_assert_not_reached();
3207 g_assert_not_reached();
3214 hfinfo_uint_format(header_field_info *hfinfo)
3216 char *format = NULL;
3218 /* Pick the proper format string */
3219 if (hfinfo->type == FT_FRAMENUM) {
3221 * Frame numbers are always displayed in decimal.
3225 switch(hfinfo->display) {
3229 case BASE_OCT: /* I'm lazy */
3233 switch(hfinfo->type) {
3235 format = "%s: 0x%02x";
3238 format = "%s: 0x%04x";
3241 format = "%s: 0x%06x";
3244 format = "%s: 0x%08x";
3247 g_assert_not_reached();
3252 g_assert_not_reached();
3260 hfinfo_int_vals_format(header_field_info *hfinfo)
3262 char *format = NULL;
3264 switch(hfinfo->display) {
3266 format = "%s: %s (%d)";
3268 case BASE_OCT: /* I'm lazy */
3269 format = "%s: %s (%o)";
3272 switch(hfinfo->type) {
3274 format = "%s: %s (0x%02x)";
3277 format = "%s: %s (0x%04x)";
3280 format = "%s: %s (0x%06x)";
3283 format = "%s: %s (0x%08x)";
3286 g_assert_not_reached();
3291 g_assert_not_reached();
3298 hfinfo_uint64_format(header_field_info *hfinfo)
3300 char *format = NULL;
3302 /* Pick the proper format string */
3303 switch(hfinfo->display) {
3305 format = "%s: %" PRIu64;
3307 case BASE_OCT: /* I'm lazy */
3308 format = "%s: %" PRIo64;
3311 format = "%s: 0x%016" PRIx64;
3314 g_assert_not_reached();
3321 hfinfo_int_format(header_field_info *hfinfo)
3323 char *format = NULL;
3325 /* Pick the proper format string */
3326 switch(hfinfo->display) {
3330 case BASE_OCT: /* I'm lazy */
3334 switch(hfinfo->type) {
3336 format = "%s: 0x%02x";
3339 format = "%s: 0x%04x";
3342 format = "%s: 0x%06x";
3345 format = "%s: 0x%08x";
3348 g_assert_not_reached();
3353 g_assert_not_reached();
3360 hfinfo_int64_format(header_field_info *hfinfo)
3362 char *format = NULL;
3364 /* Pick the proper format string */
3365 switch(hfinfo->display) {
3367 format = "%s: %" PRId64;
3369 case BASE_OCT: /* I'm lazy */
3370 format = "%s: %" PRIo64;
3373 format = "%s: 0x%016" PRIx64;
3376 g_assert_not_reached();
3385 proto_registrar_n(void)
3387 return gpa_hfinfo.len;
3391 proto_registrar_get_name(int n)
3393 header_field_info *hfinfo;
3395 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
3396 return hfinfo->name;
3400 proto_registrar_get_abbrev(int n)
3402 header_field_info *hfinfo;
3404 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
3405 return hfinfo->abbrev;
3409 proto_registrar_get_ftype(int n)
3411 header_field_info *hfinfo;
3413 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
3414 return hfinfo->type;
3418 proto_registrar_get_parent(int n)
3420 header_field_info *hfinfo;
3422 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
3423 return hfinfo->parent;
3427 proto_registrar_is_protocol(int n)
3429 header_field_info *hfinfo;
3431 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
3432 return (hfinfo->parent == -1 ? TRUE : FALSE);
3435 /* Returns length of field in packet (not necessarily the length
3436 * in our internal representation, as in the case of IPv4).
3437 * 0 means undeterminable at time of registration
3438 * -1 means the field is not registered. */
3440 proto_registrar_get_length(int n)
3442 header_field_info *hfinfo;
3444 PROTO_REGISTRAR_GET_NTH(n, hfinfo);
3445 return ftype_length(hfinfo->type);
3450 /* Looks for a protocol or a field in a proto_tree. Returns TRUE if
3451 * it exists anywhere, or FALSE if it exists nowhere. */
3453 proto_check_for_protocol_or_field(proto_tree* tree, int id)
3455 GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
3460 else if (g_ptr_array_len(ptrs) > 0) {
3468 /* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
3469 * This only works if the hfindex was "primed" before the dissection
3470 * took place, as we just pass back the already-created GPtrArray*.
3471 * The caller should *not* free the GPtrArray*; proto_tree_free_node()
3474 proto_get_finfo_ptr_array(proto_tree *tree, int id)
3476 return g_hash_table_lookup(PTREE_DATA(tree)->interesting_hfids,
3477 GINT_TO_POINTER(id));
3481 /* Helper struct and function for proto_find_info() */
3488 find_finfo(proto_node *node, gpointer data)
3490 field_info *fi = PITEM_FINFO(node);
3491 if (fi && fi->hfinfo) {
3492 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
3493 g_ptr_array_add(((ffdata_t*)data)->array, fi);
3497 /* Don't stop traversing. */
3501 /* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
3502 * This works on any proto_tree, primed or unprimed, but actually searches
3503 * the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
3504 * The caller does need to free the returned GPtrArray with
3505 * g_ptr_array_free(<array>, FALSE).
3508 proto_find_finfo(proto_tree *tree, int id)
3512 ffdata.array = g_ptr_array_new();
3515 proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
3517 return ffdata.array;
3528 check_for_offset(proto_node *node, gpointer data)
3530 field_info *fi = PITEM_FINFO(node);
3531 offset_search_t *offsearch = data;
3533 /* !fi == the top most container node which holds nothing */
3534 if (fi && !PROTO_ITEM_IS_HIDDEN(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
3535 if (offsearch->offset >= (guint) fi->start &&
3536 offsearch->offset < (guint) (fi->start + fi->length)) {
3538 offsearch->finfo = fi;
3539 return FALSE; /* keep traversing */
3542 return FALSE; /* keep traversing */
3545 /* Search a proto_tree backwards (from leaves to root) looking for the field
3546 * whose start/length occupies 'offset' */
3547 /* XXX - I couldn't find an easy way to search backwards, so I search
3548 * forwards, w/o stopping. Therefore, the last finfo I find will the be
3549 * the one I want to return to the user. This algorithm is inefficient
3550 * and could be re-done, but I'd have to handle all the children and
3551 * siblings of each node myself. When I have more time I'll do that.
3554 proto_find_field_from_offset(proto_tree *tree, guint offset, tvbuff_t *tvb)
3556 offset_search_t offsearch;
3558 offsearch.offset = offset;
3559 offsearch.finfo = NULL;
3560 offsearch.tvb = tvb;
3562 proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
3564 return offsearch.finfo;
3567 /* Dumps the protocols in the registration database to stdout. An independent
3568 * program can take this output and format it into nice tables or HTML or
3571 * There is one record per line. The fields are tab-delimited.
3573 * Field 1 = protocol name
3574 * Field 2 = protocol short name
3575 * Field 3 = protocol filter name
3578 proto_registrar_dump_protocols(void)
3580 protocol_t *protocol;
3584 for (i = proto_get_first_protocol(&cookie); i != -1;
3585 i = proto_get_next_protocol(&cookie)) {
3586 protocol = find_protocol_by_id(i);
3587 printf("%s\t%s\t%s\n", protocol->name, protocol->short_name,
3588 protocol->filter_name);
3592 /* Dumps the value_string and true/false strings for fields that have
3593 * them. There is one record per line. Fields are tab-delimited.
3594 * There are two types of records, Value String records and True/False
3595 * String records. The first field, 'V' or 'T', indicates the type
3601 * Field 2 = field abbreviation to which this value string corresponds
3602 * Field 3 = Integer value
3605 * True/False Strings
3606 * ------------------
3608 * Field 2 = field abbreviation to which this true/false string corresponds
3609 * Field 3 = True String
3610 * Field 4 = False String
3613 proto_registrar_dump_values(void)
3615 header_field_info *hfinfo, *parent_hfinfo;
3617 const value_string *vals;
3618 const true_false_string *tfs;
3620 len = gpa_hfinfo.len;
3621 for (i = 0; i < len ; i++) {
3622 PROTO_REGISTRAR_GET_NTH(i, hfinfo);
3624 if (hfinfo->id == hf_text_only) {
3628 /* ignore protocols */
3629 if (proto_registrar_is_protocol(i)) {
3632 /* process header fields */
3635 * If this field isn't at the head of the list of
3636 * fields with this name, skip this field - all
3637 * fields with the same name are really just versions
3638 * of the same field stored in different bits, and
3639 * should have the same type/radix/value list, and
3640 * just differ in their bit masks. (If a field isn't
3641 * a bitfield, but can be, say, 1 or 2 bytes long,
3642 * it can just be made FT_UINT16, meaning the
3643 * *maximum* length is 2 bytes, and be used
3646 if (hfinfo->same_name_prev != NULL)
3649 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
3654 if (hfinfo->type == FT_UINT8 ||
3655 hfinfo->type == FT_UINT16 ||
3656 hfinfo->type == FT_UINT24 ||
3657 hfinfo->type == FT_UINT32 ||
3658 hfinfo->type == FT_UINT64 ||
3659 hfinfo->type == FT_INT8 ||
3660 hfinfo->type == FT_INT16 ||
3661 hfinfo->type == FT_INT24 ||
3662 hfinfo->type == FT_INT32 ||
3663 hfinfo->type == FT_INT64) {
3665 vals = hfinfo->strings;
3667 else if (hfinfo->type == FT_BOOLEAN) {
3668 tfs = hfinfo->strings;
3671 /* Print value strings? */
3674 while (vals[vi].strptr) {
3675 /* Print in the proper base */
3676 if (hfinfo->display == BASE_HEX) {
3677 printf("V\t%s\t0x%x\t%s\n",
3683 printf("V\t%s\t%u\t%s\n",
3692 /* Print true/false strings? */
3694 printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
3695 tfs->true_string, tfs->false_string);
3701 /* Dumps the contents of the registration database to stdout. An indepedent
3702 * program can take this output and format it into nice tables or HTML or
3705 * There is one record per line. Each record is either a protocol or a header
3706 * field, differentiated by the first field. The fields are tab-delimited.
3711 * Field 2 = descriptive protocol name
3712 * Field 3 = protocol abbreviation
3718 * Field 2 = descriptive field name
3719 * Field 3 = field abbreviation
3720 * Field 4 = type ( textual representation of the the ftenum type )
3721 * Field 5 = parent protocol abbreviation
3723 * (format 2 adds these fields:)
3724 * Field 6 = base for display (for integer types)
3725 * Field 7 = blurb describing field
3728 proto_registrar_dump_fields(int format)
3730 header_field_info *hfinfo, *parent_hfinfo;
3732 const char *enum_name;
3733 const char *base_name;
3735 len = gpa_hfinfo.len;
3736 for (i = 0; i < len ; i++) {
3737 PROTO_REGISTRAR_GET_NTH(i, hfinfo);
3740 * Skip fields with zero-length names or abbreviations;
3741 * the pseudo-field for "proto_tree_add_text()" is such
3742 * a field, and we don't want it in the list of filterable
3746 * XXX - perhaps the name and abbrev field should be null
3747 * pointers rather than null strings for that pseudo-field,
3748 * but we'd have to add checks for null pointers in some
3749 * places if we did that.
3751 * Or perhaps protocol tree items added with
3752 * "proto_tree_add_text()" should have -1 as the field index,
3753 * with no pseudo-field being used, but that might also
3754 * require special checks for -1 to be added.
3756 /* XXX - we could just skip the special text
3757 * pseudo-field by testing: if (hfinfo->id == hf_text_only)
3759 if (hfinfo->name[0] == 0 || hfinfo->abbrev[0] == 0)
3762 /* format for protocols */
3763 if (proto_registrar_is_protocol(i)) {
3764 printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
3766 /* format for header fields */
3769 * If this field isn't at the head of the list of
3770 * fields with this name, skip this field - all
3771 * fields with the same name are really just versions
3772 * of the same field stored in different bits, and
3773 * should have the same type/radix/value list, and
3774 * just differ in their bit masks. (If a field isn't
3775 * a bitfield, but can be, say, 1 or 2 bytes long,
3776 * it can just be made FT_UINT16, meaning the
3777 * *maximum* length is 2 bytes, and be used
3780 if (hfinfo->same_name_prev != NULL)
3783 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
3785 enum_name = ftype_name(hfinfo->type);
3789 if (hfinfo->type == FT_UINT8 ||
3790 hfinfo->type == FT_UINT16 ||
3791 hfinfo->type == FT_UINT24 ||
3792 hfinfo->type == FT_UINT32 ||
3793 hfinfo->type == FT_UINT64 ||
3794 hfinfo->type == FT_INT8 ||
3795 hfinfo->type == FT_INT16 ||
3796 hfinfo->type == FT_INT24 ||
3797 hfinfo->type == FT_INT32 ||
3798 hfinfo->type == FT_INT64) {
3801 switch(hfinfo->display) {
3803 base_name = "BASE_NONE";
3806 base_name = "BASE_DEC";
3809 base_name = "BASE_HEX";
3812 base_name = "BASE_OCT";
3819 printf("F\t%s\t%s\t%s\t%s\t%s\n", hfinfo->name, hfinfo->abbrev,
3820 enum_name,parent_hfinfo->abbrev, hfinfo->blurb);
3822 else if (format == 2) {
3823 printf("F\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n",
3824 hfinfo->name, hfinfo->abbrev,
3825 enum_name,parent_hfinfo->abbrev, hfinfo->blurb,
3826 base_name, hfinfo->blurb);
3833 hfinfo_numeric_format(header_field_info *hfinfo)
3835 char *format = NULL;
3837 /* Pick the proper format string */
3838 if (hfinfo->type == FT_FRAMENUM) {
3840 * Frame numbers are always displayed in decimal.
3842 format = "%s == %u";
3844 /* Pick the proper format string */
3845 switch(hfinfo->display) {
3847 case BASE_OCT: /* I'm lazy */
3848 switch(hfinfo->type) {
3853 format = "%s == %u";
3856 format = "%s == %" PRIu64;
3862 format = "%s == %d";
3865 format = "%s == %" PRId64;
3868 g_assert_not_reached();
3873 switch(hfinfo->type) {
3875 format = "%s == 0x%02x";
3878 format = "%s == 0x%04x";
3881 format = "%s == 0x%06x";
3884 format = "%s == 0x%08x";
3887 format = "%s == 0x%016" PRIx64;
3890 g_assert_not_reached();
3895 g_assert_not_reached();
3903 * Returns TRUE if we can do a "match selected" on the field, FALSE
3907 proto_can_match_selected(field_info *finfo, epan_dissect_t *edt)
3909 header_field_info *hfinfo;
3912 hfinfo = finfo->hfinfo;
3915 switch(hfinfo->type) {
3934 case FT_ABSOLUTE_TIME:
3935 case FT_RELATIVE_TIME:
3938 case FT_UINT_STRING:
3944 * These all have values, so we can match.
3950 * This doesn't have a value, so we'd match
3951 * on the raw bytes at this address.
3953 * Should we be allowed to access to the raw bytes?
3954 * If "edt" is NULL, the answer is "no".
3960 * Is this field part of the raw frame tvbuff?
3961 * If not, we can't use "frame[N:M]" to match
3964 * XXX - should this be frame-relative, or
3965 * protocol-relative?
3967 * XXX - does this fallback for non-registered
3968 * fields even make sense?
3970 if (finfo->ds_tvb != edt->tvb)
3974 * If the length is 0, there's nothing to match, so
3975 * we can't match. (Also check for negative values,
3976 * just in case, as we'll cast it to an unsigned
3979 length = finfo->length;
3984 * Don't go past the end of that tvbuff.
3986 if ((guint)length > tvb_length(finfo->ds_tvb))
3987 length = tvb_length(finfo->ds_tvb);
3995 proto_construct_dfilter_string(field_info *finfo, epan_dissect_t *edt)
3997 header_field_info *hfinfo;
3999 char *buf, *stringified, *format, *ptr;
4001 gint start, length, length_remaining;
4004 hfinfo = finfo->hfinfo;
4006 abbrev_len = strlen(hfinfo->abbrev);
4009 * XXX - we should add "val_to_string_repr" and "string_repr_len"
4010 * functions for more types, and use them whenever possible.
4012 * The FT_UINT and FT_INT types are the only tricky ones, as
4013 * we choose the base in the string expression based on the
4014 * display base of the field.
4016 * Note that the base does matter, as this is also used for
4017 * the protocolinfo tap.
4019 * It might be nice to use that in "proto_item_fill_label()"
4020 * as well, although, there, you'd have to deal with the base
4021 * *and* with resolved values for addresses.
4023 * Perhaps we need two different val_to_string routines, one
4024 * to generate items for display filters and one to generate
4025 * strings for display, and pass to both of them the
4026 * "display" and "strings" values in the header_field_info
4027 * structure for the field, so they can get the base and,
4028 * if the field is Boolean or an enumerated integer type,
4029 * the tables used to generate human-readable values.
4031 switch(hfinfo->type) {
4043 * 4 bytes for " == ".
4046 * a sign + up to 10 digits of 32-bit integer,
4049 * "0x" + 8 digits of 32-bit integer, in hex;
4051 * 11 digits of 32-bit integer, in octal.
4052 * (No, we don't do octal, but this way,
4053 * we know that if we do, this will still
4056 * 1 byte for the trailing '\0'.
4058 dfilter_len = abbrev_len + 4 + 11 + 1;
4059 buf = g_malloc0(dfilter_len);
4060 format = hfinfo_numeric_format(hfinfo);
4061 snprintf(buf, dfilter_len, format, hfinfo->abbrev, fvalue_get_integer(&finfo->value));
4067 * 4 bytes for " == ".
4070 * a sign + up to 20 digits of 32-bit integer,
4073 * "0x" + 16 digits of 32-bit integer, in hex;
4075 * 22 digits of 32-bit integer, in octal.
4076 * (No, we don't do octal, but this way,
4077 * we know that if we do, this will still
4080 * 1 byte for the trailing '\0'.
4082 dfilter_len = abbrev_len + 4 + 22 + 1;
4083 buf = g_malloc0(dfilter_len);
4084 format = hfinfo_numeric_format(hfinfo);
4085 snprintf(buf, dfilter_len, format, hfinfo->abbrev, fvalue_get_integer64(&finfo->value));
4090 * 4 bytes for " == ".
4092 * 8 bytes for 8 digits of 32-bit hex number.
4093 * 1 byte for the trailing '\0'.
4095 dfilter_len = abbrev_len + 4 + 2 + 8 + 1;
4096 buf = g_malloc0(dfilter_len);
4097 snprintf(buf, dfilter_len, "%s == 0x%08x", hfinfo->abbrev,
4098 fvalue_get_integer(&finfo->value));
4103 * 4 bytes for " == ".
4104 * N bytes for the string for the address.
4105 * 1 byte for the trailing '\0'.
4107 stringified = ip6_to_str((struct e_in6_addr*) fvalue_get(&finfo->value));
4108 dfilter_len = abbrev_len + 4 + strlen(stringified) + 1;
4109 buf = g_malloc0(dfilter_len);
4110 snprintf(buf, dfilter_len, "%s == %s", hfinfo->abbrev,
4114 /* These use the fvalue's "to_string_repr" method. */
4122 case FT_ABSOLUTE_TIME:
4123 case FT_RELATIVE_TIME:
4125 /* Figure out the string length needed.
4126 * The ft_repr length.
4127 * 4 bytes for " == ".
4128 * 1 byte for trailing NUL.
4130 dfilter_len = fvalue_string_repr_len(&finfo->value,
4132 dfilter_len += abbrev_len + 4 + 1;
4133 buf = g_malloc0(dfilter_len);
4135 /* Create the string */
4136 snprintf(buf, dfilter_len, "%s == ", hfinfo->abbrev);
4137 fvalue_to_string_repr(&finfo->value,
4139 &buf[abbrev_len + 4]);
4143 buf = g_strdup(finfo->hfinfo->abbrev);
4148 * This doesn't have a value, so we'd match
4149 * on the raw bytes at this address.
4151 * Should we be allowed to access to the raw bytes?
4152 * If "edt" is NULL, the answer is "no".
4158 * Is this field part of the raw frame tvbuff?
4159 * If not, we can't use "frame[N:M]" to match
4162 * XXX - should this be frame-relative, or
4163 * protocol-relative?
4165 * XXX - does this fallback for non-registered
4166 * fields even make sense?
4168 if (finfo->ds_tvb != edt->tvb)
4169 return NULL; /* you lose */
4172 * If the length is 0, there's nothing to match, so
4173 * we can't match. (Also check for negative values,
4174 * just in case, as we'll cast it to an unsigned
4177 length = finfo->length;
4182 * Don't go past the end of that tvbuff.
4184 length_remaining = tvb_length_remaining(finfo->ds_tvb, finfo->start);
4185 if (length > length_remaining)
4186 length = length_remaining;
4190 start = finfo->start;
4191 buf = g_malloc0(32 + length * 3);
4194 sprintf(ptr, "frame[%d:%d] == ", finfo->start, length);
4195 ptr = buf+strlen(buf);
4197 for (i=0;i<length; i++) {
4198 c = tvb_get_guint8(finfo->ds_tvb, start);
4201 sprintf(ptr, "%02x", c);
4204 sprintf(ptr, ":%02x", c);
4206 ptr = buf+strlen(buf);