#include "ptvcursor.h"
#include "strutil.h"
#include "addr_resolv.h"
-#include "oid_resolv.h"
+#include "oids.h"
#include "plugins.h"
#include "proto.h"
#include "epan_dissect.h"
#include "slab.h"
#include "tvbuff.h"
#include "emem.h"
+#include "charsets.h"
+#include "asm_utils.h"
+#include "column-utils.h"
+
+#ifdef NEED_G_ASCII_STRCASECMP_H
+#include "g_ascii_strcasecmp.h"
+#endif
#define SUBTREE_ONCE_ALLOCATION_NUMBER 8
#define SUBTREE_MAX_LEVELS 256
gint offset;
};
+/* Candidates for assembler */
+int
+wrs_count_bitshift(guint32 bitmask)
+{
+ int bitshift = 0;
+
+ while ((bitmask & (1 << bitshift)) == 0)
+ bitshift++;
+ return bitshift;
+}
+
+
+
#if GLIB_MAJOR_VERSION < 2
static void *discard_const(const void *const_ptr)
{
- union {
+ union {
const void *const_ptr;
void *ptr;
} stupid_const;
or else filtering will not work (they would be ignored since tree\
would be NULL). \
DONT try to fake a node where PITEM_FINFO(pi) is NULL \
- since dissectors that want to do proto_item_set_len() ot \
+ since dissectors that want to do proto_item_set_len() or \
other operations that dereference this would crash. \
We dont fake FT_PROTOCOL either since these are cheap and \
some stuff (proto hier stat) assumes they always exist. \
int hfinfo_bitwidth(header_field_info *hfinfo);
static const char* hfinfo_uint_vals_format(header_field_info *hfinfo);
static const char* hfinfo_uint_format(header_field_info *hfinfo);
+static const char* hfinfo_uint_value_format(header_field_info *hfinfo);
static const char* hfinfo_uint64_format(header_field_info *hfinfo);
static const char* hfinfo_int_vals_format(header_field_info *hfinfo);
static const char* hfinfo_int_format(header_field_info *hfinfo);
+static const char* hfinfo_int_value_format(header_field_info *hfinfo);
static const char* hfinfo_int64_format(header_field_info *hfinfo);
static proto_item*
static void
proto_tree_set_string_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
static void
+proto_tree_set_ebcdic_string_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length);
+static void
proto_tree_set_ether(field_info *fi, const guint8* value);
static void
proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, gint start);
static void
proto_tree_set_uint64(field_info *fi, guint64 value);
static void
-proto_tree_set_uint64_tvb(field_info *fi, tvbuff_t *tvb, gint start, gboolean little_endian);
+proto_tree_set_uint64_tvb(field_info *fi, tvbuff_t *tvb, gint start, guint length, gboolean little_endian);
static int proto_register_field_init(header_field_info *hfinfo, int parent);
-/* Comparision function for tree insertion. A wrapper around strcmp() */
-static int g_strcmp(gconstpointer a, gconstpointer b);
-
/* special-case header field used within proto.c */
int hf_text_only = -1;
/* Balanced tree of abbreviations and IDs */
static GTree *gpa_name_tree = NULL;
+static header_field_info *same_name_hfinfo;
+
+#if GLIB_MAJOR_VERSION >= 2
+static void save_same_name_hfinfo(gpointer data)
+{
+ same_name_hfinfo = (header_field_info*)data;
+}
+#endif
/* Points to the first element of an array of Booleans, indexed by
a subtree item type; that array element is TRUE if subtrees of
const protocol_t *p1 = p1_arg;
const protocol_t *p2 = p2_arg;
- return g_strcasecmp(p1->short_name, p2->short_name);
+ return g_ascii_strcasecmp(p1->short_name, p2->short_name);
}
{
static hf_register_info hf[] = {
{ &hf_text_only,
- { "Proto Init", "", FT_NONE, BASE_NONE, NULL, 0x0,
+ { "Text item", "", FT_NONE, BASE_NONE, NULL, 0x0,
NULL, HFILL }},
};
proto_names = g_hash_table_new(g_int_hash, g_int_equal);
- proto_short_names = g_hash_table_new(g_int_hash, g_int_equal);
- proto_filter_names = g_hash_table_new(g_int_hash, g_int_equal);
+ proto_short_names = g_hash_table_new(wrs_str_hash, g_str_equal);
+ proto_filter_names = g_hash_table_new(wrs_str_hash, g_str_equal);
proto_cleanup();
gpa_hfinfo.len=0;
gpa_hfinfo.allocated_len=0;
gpa_hfinfo.hfi=NULL;
- gpa_name_tree = g_tree_new(g_strcmp);
+#if GLIB_MAJOR_VERSION < 2
+ gpa_name_tree = g_tree_new(wrs_strcmp);
+#else
+ gpa_name_tree = g_tree_new_full(wrs_strcmp_with_data, NULL, NULL, save_same_name_hfinfo);
+#endif
/* Initialize the ftype subsystem */
ftypes_initialize();
#ifdef HAVE_PLUGINS
/* Now scan for plugins and load all the ones we find, calling
their register routines to do the stuff described above. */
- if(cb)
+ if(cb)
(*cb)(RA_PLUGIN_REGISTER, NULL, client_data);
init_plugins();
register_all_plugin_registrations();
#ifdef HAVE_PLUGINS
/* Now do the same with plugins. */
- if(cb)
+ if(cb)
(*cb)(RA_PLUGIN_HANDOFF, NULL, client_data);
register_all_plugin_handoffs();
#endif
memset(tree_is_expanded, 0, num_tree_types*sizeof (gboolean));
}
-/* String comparison func for dfilter_token GTree */
-static int
-g_strcmp(gconstpointer a, gconstpointer b)
-{
- return strcmp((const char*)a, (const char*)b);
-}
-
void
proto_cleanup(void)
{
ptvc->tree = tree;
}
-/* creates a subtree, sets it as the working tree and pushes the old working tree */
-proto_tree*
-ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree)
+/* creates a subtree, sets it as the working tree and pushes the old working tree */
+proto_tree*
+ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree)
{
subtree_lvl * subtree;
if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
}
/* pops a subtree */
-void
-ptvcursor_pop_subtree(ptvcursor_t *ptvc)
+void
+ptvcursor_pop_subtree(ptvcursor_t *ptvc)
{
subtree_lvl * subtree;
if (ptvc->pushed_tree_index <= 0)
ptvc->pushed_tree_index--;
subtree = ptvc->pushed_tree+ptvc->pushed_tree_index;
- if (subtree->it != NULL)
+ if (subtree->it != NULL)
proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
ptvc->tree = subtree->tree;
}
/* Creates a subtree and adds it to the cursor as the working tree but does not
* save the old working tree */
-proto_tree*
-ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree)
+proto_tree*
+ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, gint ett_subtree)
{
ptvc->tree = proto_item_add_subtree(it, ett_subtree);
return ptvc->tree;
* In this case, when the subtree will be closed, the parent item length will
* be equal to the advancement of the cursor since the creation of the subtree.
*/
-proto_tree* ptvcursor_add_with_subtree(ptvcursor_t * ptvc, int hfindex, gint length,
+proto_tree* ptvcursor_add_with_subtree(ptvcursor_t * ptvc, int hfindex, gint length,
gboolean little_endian, gint ett_subtree)
{
proto_item * it;
* In this case, when the subtree will be closed, the item length will be equal
* to the advancement of the cursor since the creation of the subtree.
*/
-proto_tree * ptvcursor_add_text_with_subtree(ptvcursor_t * ptvc, gint length,
+proto_tree * ptvcursor_add_text_with_subtree(ptvcursor_t * ptvc, gint length,
gint ett_subtree, const char *format, ...)
{
proto_item * it;
va_list ap;
- it = proto_tree_add_text_node(ptvcursor_tree(ptvc), ptvcursor_tvbuff(ptvc),
+ it = proto_tree_add_text_node(ptvcursor_tree(ptvc), ptvcursor_tvbuff(ptvc),
ptvcursor_current_offset(ptvc), length);
va_start(ap, format);
va_list ap;
pi = proto_tree_add_text_node(tree, NULL, 0, 0);
- if (pi == NULL)
- return(NULL);
va_start(ap, format);
- proto_tree_set_representation(pi, format, ap);
+ if (pi)
+ proto_tree_set_representation(pi, format, ap);
vprintf(format, ap);
va_end(ap);
printf("\n");
case FT_INT64:
case FT_UINT64:
- DISSECTOR_ASSERT(length == 8);
- proto_tree_set_uint64_tvb(new_fi, tvb, start, little_endian);
+ DISSECTOR_ASSERT( length <= 8 && length >= 1);
+ proto_tree_set_uint64_tvb(new_fi, tvb, start, length, little_endian);
break;
/* XXX - make these just FT_INT? */
proto_tree_set_string(new_fi, string);
break;
+ case FT_EBCDIC:
+ proto_tree_set_ebcdic_string_tvb(new_fi, tvb, start, length);
+ break;
+
case FT_UINT_STRING:
n = get_uint_value(tvb, start, length, little_endian);
proto_tree_set_string_tvb(new_fi, tvb, start + length, n);
if (length > 0) {
g_byte_array_append(bytes, start_ptr, length);
}
+ col_custom_set_fstr(fi->hfinfo, "%s", bytes_to_str(bytes->data,
+ length));
fvalue_set(&fi->value, bytes, TRUE);
}
static void
proto_tree_set_time(field_info *fi, nstime_t *value_ptr)
{
+ header_field_info *hfinfo;
+
DISSECTOR_ASSERT(value_ptr != NULL);
+ hfinfo = fi->hfinfo;
+
+ if (hfinfo->type == FT_ABSOLUTE_TIME) {
+ col_custom_set_fstr(fi->hfinfo, "%s", abs_time_to_str(value_ptr));
+ } else if (hfinfo->type == FT_RELATIVE_TIME) {
+ col_custom_set_fstr(fi->hfinfo, "%s", rel_time_to_secs_str(value_ptr));
+ }
fvalue_set(&fi->value, value_ptr, FALSE);
}
static void
proto_tree_set_ipv4(field_info *fi, guint32 value)
{
+ col_custom_set_fstr(fi->hfinfo, "%s",
+ ip_to_str((guint8 *)&value));
fvalue_set_uinteger(&fi->value, value);
}
proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
{
DISSECTOR_ASSERT(value_ptr != NULL);
+ col_custom_set_fstr(fi->hfinfo, "%s",
+ guid_to_str(value_ptr));
fvalue_set(&fi->value, (gpointer) value_ptr, FALSE);
}
if (length > 0) {
g_byte_array_append(bytes, value_ptr, length);
}
+ col_custom_set_fstr(fi->hfinfo, "%s",
+ oid_resolved_from_encoded(value_ptr, length));
fvalue_set(&fi->value, bytes, TRUE);
}
static void
proto_tree_set_uint64(field_info *fi, guint64 value)
{
+ col_custom_set_fstr(fi->hfinfo, "%" G_GINT64_MODIFIER "u",
+ value);
fvalue_set_integer64(&fi->value, value);
}
static void
-proto_tree_set_uint64_tvb(field_info *fi, tvbuff_t *tvb, gint start, gboolean little_endian)
+proto_tree_set_uint64_tvb(field_info *fi, tvbuff_t *tvb, gint start, guint length, gboolean little_endian)
{
- guint64 value;
-
- value = little_endian ? tvb_get_letoh64(tvb, start)
- : tvb_get_ntoh64(tvb, start);
+ guint64 value = 0;
+ guint8* b = ep_tvb_memdup(tvb,start,length);
+
+ if(little_endian) {
+ b += length;
+ switch(length) {
+ default: DISSECTOR_ASSERT_NOT_REACHED();
+ case 8: value <<= 8; value += *--b;
+ case 7: value <<= 8; value += *--b;
+ case 6: value <<= 8; value += *--b;
+ case 5: value <<= 8; value += *--b;
+ case 4: value <<= 8; value += *--b;
+ case 3: value <<= 8; value += *--b;
+ case 2: value <<= 8; value += *--b;
+ case 1: value <<= 8; value += *--b;
+ break;
+ }
+ } else {
+ switch(length) {
+ default: DISSECTOR_ASSERT_NOT_REACHED();
+ case 8: value <<= 8; value += *b++;
+ case 7: value <<= 8; value += *b++;
+ case 6: value <<= 8; value += *b++;
+ case 5: value <<= 8; value += *b++;
+ case 4: value <<= 8; value += *b++;
+ case 3: value <<= 8; value += *b++;
+ case 2: value <<= 8; value += *b++;
+ case 1: value <<= 8; value += *b++;
+ break;
+ }
+ }
proto_tree_set_uint64(fi, value);
}
* IF you must use this function you MUST also disable the
* TRY_TO_FAKE_THIS_ITEM() optimization for your dissector/function
* using proto_item_append_string().
- * Do that by faking that the tree is visible by setting :
- * PTREE_DATA(tree)->visible=1; (see packet-wsp.c)
+ * Do that by faking that the tree is visible by calling
+ * proto_tree_set_visible(tree, TRUE) (see packet-wsp.c)
* BEFORE you create the item you are later going to use
* proto_item_append_string() on.
*/
static void
proto_tree_set_string(field_info *fi, const char* value)
{
- if (value)
+ if (value) {
+ col_custom_set_fstr(fi->hfinfo, "%s",
+ format_text(value, strlen(value)));
fvalue_set(&fi->value, (gpointer) value, FALSE);
- else
+ } else {
+ col_custom_set_fstr(fi->hfinfo, "[ Null ]");
fvalue_set(&fi->value, (gpointer) "[ Null ]", FALSE);
+ }
}
static void
proto_tree_set_string(fi, string);
}
+static void
+proto_tree_set_ebcdic_string_tvb(field_info *fi, tvbuff_t *tvb, gint start, gint length)
+{
+ gchar *string;
+
+ if (length == -1) {
+ length = tvb_ensure_length_remaining(tvb, start);
+ }
+
+ string = tvb_get_ephemeral_string(tvb, start, length);
+ EBCDIC_to_ASCII(string, length);
+ proto_tree_set_string(fi, string);
+}
+
/* Add a FT_ETHER to a proto_tree */
proto_item *
proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length,
static void
proto_tree_set_ether(field_info *fi, const guint8* value)
{
+ col_custom_set_fstr(fi->hfinfo, "%s", bytes_to_str_punct(value, 6, ':'));
fvalue_set(&fi->value, (gpointer) value, FALSE);
}
static void
proto_tree_set_float(field_info *fi, float value)
{
+ col_custom_set_fstr(fi->hfinfo, "%." STRINGIFY(FLT_DIG) "f",
+ value);
fvalue_set_floating(&fi->value, value);
}
static void
proto_tree_set_double(field_info *fi, double value)
{
+ col_custom_set_fstr(fi->hfinfo, "%." STRINGIFY(DBL_DIG) "g",
+ value);
fvalue_set_floating(&fi->value, value);
}
integer >>= hfinfo->bitshift;
}
}
+
+ if (hfinfo->type == FT_BOOLEAN) {
+ const true_false_string *tfstring = &tfs_true_false;
+ if (hfinfo->strings) {
+ tfstring = (const struct true_false_string*) hfinfo->strings;
+ }
+ col_custom_set_fstr(fi->hfinfo, "%s", value ? tfstring->true_string : tfstring->false_string);
+ } else if (hfinfo->strings) {
+ col_custom_set_fstr(fi->hfinfo, "%s", val_to_str(integer, cVALS(hfinfo->strings), "%d"));
+ } else if (IS_BASE_DUAL(hfinfo->display)) {
+ col_custom_set_fstr(fi->hfinfo, hfinfo_uint_value_format(hfinfo), integer, integer);
+ } else {
+ col_custom_set_fstr(fi->hfinfo, hfinfo_uint_value_format(hfinfo), integer);
+ }
fvalue_set_uinteger(&fi->value, integer);
}
integer >>= hfinfo->bitshift;
}
}
+
+ if (hfinfo->strings) {
+ col_custom_set_fstr(fi->hfinfo, "%s", val_to_str(integer, cVALS(hfinfo->strings), "%d"));
+ } else if (IS_BASE_DUAL(hfinfo->display)) {
+ col_custom_set_fstr(fi->hfinfo, hfinfo_int_value_format(hfinfo), integer, integer);
+ } else {
+ col_custom_set_fstr(fi->hfinfo, hfinfo_int_value_format(hfinfo), integer);
+ }
fvalue_set_sinteger(&fi->value, integer);
}
/* add the data source tvbuff */
fi->ds_tvb=tvb?TVB_GET_DS_TVB(tvb):NULL;
+ fi->appendix_start = 0;
+ fi->appendix_length = 0;
+
return fi;
}
fi = PITEM_FINFO(pi);
DISSECTOR_ASSERT(length >= 0);
fi->length = length;
+
+ if (fi->value.ftype->ftype == FT_BYTES)
+ fi->value.value.bytes->len = length;
}
/*
}
gboolean
-proto_item_set_expert_flags(proto_item *pi, int group, int severity)
+proto_item_set_expert_flags(proto_item *pi, int group, guint severity)
{
if(pi == NULL || pi->finfo == NULL)
return FALSE;
}
}
+void
+proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, gint start, gint length)
+{
+ field_info *fi;
+
+ if (tree == NULL)
+ return;
+
+ fi = tree->finfo;
+ start += TVB_RAW_OFFSET(tvb);
+ DISSECTOR_ASSERT(start >= 0);
+ DISSECTOR_ASSERT(length >= 0);
+
+ fi->appendix_start = start;
+ fi->appendix_length = length;
+}
int
proto_register_protocol(const char *name, const char *short_name, const char *filter_name)
*/
key = g_malloc (sizeof(gint));
- *key = g_str_hash(name);
+ *key = wrs_str_hash(name);
existing_name = g_hash_table_lookup(proto_names, key);
if (existing_name != NULL) {
/* g_error will terminate the program */
}
g_hash_table_insert(proto_names, key, (gpointer)name);
- key = g_malloc (sizeof(gint));
- *key = g_str_hash(short_name);
- existing_name = g_hash_table_lookup(proto_short_names, key);
+ existing_name = g_hash_table_lookup(proto_short_names, (gpointer)short_name);
if (existing_name != NULL) {
g_error("Duplicate protocol short_name \"%s\"!"
" This might be caused by an inappropriate plugin or a development error.", short_name);
}
- g_hash_table_insert(proto_short_names, key, (gpointer)short_name);
+ g_hash_table_insert(proto_short_names, (gpointer)short_name, (gpointer)short_name);
found_invalid = FALSE;
for (i = 0; i < strlen(filter_name); i++) {
" Allowed are lower characters, digits, '-', '_' and '.'."
" This might be caused by an inappropriate plugin or a development error.", filter_name);
}
- key = g_malloc (sizeof(gint));
- *key = g_str_hash(filter_name);
- existing_name = g_hash_table_lookup(proto_filter_names, key);
+ existing_name = g_hash_table_lookup(proto_filter_names, (gpointer)filter_name);
if (existing_name != NULL) {
g_error("Duplicate protocol filter_name \"%s\"!"
" This might be caused by an inappropriate plugin or a development error.", filter_name);
}
- g_hash_table_insert(proto_filter_names, key, (gpointer)filter_name);
+ g_hash_table_insert(proto_filter_names, (gpointer)filter_name, (gpointer)filter_name);
/* Add this protocol to the list of known protocols; the list
is sorted by protocol short name. */
protocol->is_enabled = TRUE; /* protocol is enabled by default */
protocol->can_toggle = TRUE;
/* list will be sorted later by name, when all protocols completed registering */
- protocols = g_list_append(protocols, protocol);
+ protocols = g_list_prepend(protocols, protocol);
/* Here we do allocate a new header_field_info struct */
hfinfo = g_mem_chunk_alloc(gmc_hfinfo);
protocol_t *protocol;
protocol = find_protocol_by_id(proto_id);
+ if (protocol == NULL)
+ return "(none)";
return protocol->filter_name;
}
protocol->is_enabled = enabled;
}
+void
+proto_enable_all(void)
+{
+ protocol_t *protocol;
+ GList *list_item = protocols;
+
+ if (protocols == NULL)
+ return;
+
+ while (list_item) {
+ protocol = list_item->data;
+ if (protocol->can_toggle)
+ protocol->is_enabled = TRUE;
+ list_item = g_list_next(list_item);
+ }
+}
+
void
proto_set_cant_toggle(int proto_id)
{
}
}
-static int
-proto_register_field_init(header_field_info *hfinfo, int parent)
-{
+/* chars allowed in field abbrev */
+static
+const guchar fld_abbrev_chars[256] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00-0x0F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10-0x1F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, /* 0x20-0x2F '-', '.' */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 0x30-0x3F '0'-'9' */
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40-0x4F 'A'-'O' */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 0x50-0x5F 'P'-'Z', '_' */
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x60-0x6F 'a'-'o' */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 0x70-0x7F 'p'-'z' */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80-0x8F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90-0x9F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xA0-0xAF */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xB0-0xBF */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xC0-0xCF */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xD0-0xDF */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xE0-0xEF */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xF0-0xFF */
+};
+
+/* temporary function containing assert part for easier profiling */
+static void tmp_fld_check_assert(header_field_info *hfinfo) {
/* The field must have a name (with length > 0) */
DISSECTOR_ASSERT(hfinfo->name && hfinfo->name[0]);
default:
break;
}
+}
+
+static int
+proto_register_field_init(header_field_info *hfinfo, int parent)
+{
+
+ tmp_fld_check_assert(hfinfo);
+
/* if this is a bitfield, compute bitshift */
if (hfinfo->bitmask) {
- while ((hfinfo->bitmask & (1 << hfinfo->bitshift)) == 0)
- hfinfo->bitshift++;
+ hfinfo->bitshift = wrs_count_bitshift(hfinfo->bitmask);
}
hfinfo->parent = parent;
/* if we have real names, enter this field in the name tree */
if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) {
- header_field_info *same_name_hfinfo, *same_name_next_hfinfo;
- const char *p;
+ header_field_info *same_name_next_hfinfo;
guchar c;
/* Check that the filter name (abbreviation) is legal;
* it must contain only alphanumerics, '-', "_", and ".". */
- for (p = hfinfo->abbrev; (c = *p) != '\0'; p++) {
- if (!(isalnum(c) || c == '-' || c == '_' || c == '.')) {
- fprintf(stderr, "OOPS: '%c' in '%s'\n", c, hfinfo->abbrev);
- DISSECTOR_ASSERT(isalnum(c) || c == '-' || c == '_' ||
- c == '.');
- }
+ c = wrs_check_charset(fld_abbrev_chars, hfinfo->abbrev);
+ if (c) {
+ fprintf(stderr, "OOPS: '%c' in '%s'\n", c, hfinfo->abbrev);
+ DISSECTOR_ASSERT(!c);
}
+
/* We allow multiple hfinfo's to be registered under the same
* abbreviation. This was done for X.25, as, depending
* on whether it's modulo-8 or modulo-128 operation,
#if GLIB_MAJOR_VERSION < 2
same_name_hfinfo = g_tree_lookup(gpa_name_tree, discard_const(hfinfo->abbrev));
#else
- same_name_hfinfo = g_tree_lookup(gpa_name_tree, hfinfo->abbrev);
+ same_name_hfinfo = NULL;
#endif
+ g_tree_insert(gpa_name_tree, (gpointer) (hfinfo->abbrev), hfinfo);
+ /* GLIB 2.x - if it is already present
+ * the previous hfinfo with the same name is saved
+ * to same_name_hfinfo by value destroy callback */
if (same_name_hfinfo) {
/* There's already a field with this name.
* Put it after that field in the list of
same_name_hfinfo->same_name_next = hfinfo;
hfinfo->same_name_prev = same_name_hfinfo;
}
- g_tree_insert(gpa_name_tree, (gpointer) (hfinfo->abbrev), hfinfo);
}
return hfinfo->id;
case FT_OID:
bytes = fvalue_get(&fi->value);
- name = (oid_resolv_enabled()) ? get_oid_name(bytes, fvalue_length(&fi->value)) : NULL;
+ name = oid_resolved_from_encoded(bytes, fvalue_length(&fi->value));
if (name) {
ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
"%s: %s (%s)", hfinfo->name,
- oid_to_str(bytes, fvalue_length(&fi->value)), name);
+ oid_encoded2string(bytes, fvalue_length(&fi->value)), name);
} else {
ret = g_snprintf(label_str, ITEM_LABEL_LENGTH,
"%s: %s", hfinfo->name,
- oid_to_str(bytes, fvalue_length(&fi->value)));
+ oid_encoded2string(bytes, fvalue_length(&fi->value)));
}
if ((ret == -1) || (ret >= ITEM_LABEL_LENGTH))
label_str[ITEM_LABEL_LENGTH - 1] = '\0';
case FT_STRING:
case FT_STRINGZ:
+ case FT_EBCDIC:
case FT_UINT_STRING:
bytes = fvalue_get(&fi->value);
if(strlen(bytes) > ITEM_LABEL_LENGTH) {
return format;
}
+static const char*
+hfinfo_uint_value_format(header_field_info *hfinfo)
+{
+ const char *format = NULL;
+
+ /* Pick the proper format string */
+ if (hfinfo->type == FT_FRAMENUM) {
+ /*
+ * Frame numbers are always displayed in decimal.
+ */
+ format = "%u";
+ } else {
+ switch(hfinfo->display) {
+ case BASE_DEC:
+ format = "%u";
+ break;
+ case BASE_DEC_HEX:
+ switch(hfinfo->type) {
+ case FT_UINT8:
+ format = "%u (0x%02x)";
+ break;
+ case FT_UINT16:
+ format = "%u (0x%04x)";
+ break;
+ case FT_UINT24:
+ format = "%u (0x%06x)";
+ break;
+ case FT_UINT32:
+ format = "%u (0x%08x)";
+ break;
+ default:
+ DISSECTOR_ASSERT_NOT_REACHED();
+ ;
+ }
+ break;
+ case BASE_OCT:
+ format = "%o";
+ break;
+ case BASE_HEX:
+ switch(hfinfo->type) {
+ case FT_UINT8:
+ format = "0x%02x";
+ break;
+ case FT_UINT16:
+ format = "0x%04x";
+ break;
+ case FT_UINT24:
+ format = "0x%06x";
+ break;
+ case FT_UINT32:
+ format = "0x%08x";
+ break;
+ default:
+ DISSECTOR_ASSERT_NOT_REACHED();
+ ;
+ }
+ break;
+ case BASE_HEX_DEC:
+ switch(hfinfo->type) {
+ case FT_UINT8:
+ format = "0x%02x (%u)";
+ break;
+ case FT_UINT16:
+ format = "0x%04x (%u)";
+ break;
+ case FT_UINT24:
+ format = "0x%06x (%u)";
+ break;
+ case FT_UINT32:
+ format = "0x%08x (%u)";
+ break;
+ default:
+ DISSECTOR_ASSERT_NOT_REACHED();
+ ;
+ }
+ break;
+ default:
+ DISSECTOR_ASSERT_NOT_REACHED();
+ ;
+ }
+ }
+ return format;
+}
+
static const char*
hfinfo_int_vals_format(header_field_info *hfinfo)
{
DISSECTOR_ASSERT_NOT_REACHED();
;
}
+ break;
case BASE_OCT: /* I'm lazy */
format = "%s: %o";
break;
return format;
}
+static const char*
+hfinfo_int_value_format(header_field_info *hfinfo)
+{
+ const char *format = NULL;
+
+ /* Pick the proper format string */
+ switch(hfinfo->display) {
+ case BASE_DEC:
+ format = "%d";
+ break;
+ case BASE_DEC_HEX:
+ switch(hfinfo->type) {
+ case FT_INT8:
+ format = "%d (0x%02x)";
+ break;
+ case FT_INT16:
+ format = "%d (0x%04x)";
+ break;
+ case FT_INT24:
+ format = "%d (0x%06x)";
+ break;
+ case FT_INT32:
+ format = "%d (0x%08x)";
+ break;
+ default:
+ DISSECTOR_ASSERT_NOT_REACHED();
+ ;
+ }
+ break;
+ case BASE_OCT:
+ format = "%o";
+ break;
+ case BASE_HEX:
+ switch(hfinfo->type) {
+ case FT_INT8:
+ format = "0x%02x";
+ break;
+ case FT_INT16:
+ format = "0x%04x";
+ break;
+ case FT_INT24:
+ format = "0x%06x";
+ break;
+ case FT_INT32:
+ format = "0x%08x";
+ break;
+ default:
+ DISSECTOR_ASSERT_NOT_REACHED();
+ ;
+ }
+ break;
+ case BASE_HEX_DEC:
+ switch(hfinfo->type) {
+ case FT_INT8:
+ format = "0x%02x (%d)";
+ break;
+ case FT_INT16:
+ format = "0x%04x (%d)";
+ break;
+ case FT_INT24:
+ format = "0x%06x (%d)";
+ break;
+ case FT_INT32:
+ format = "0x%08x (%d)";
+ break;
+ default:
+ DISSECTOR_ASSERT_NOT_REACHED();
+ ;
+ }
+ break;
+ default:
+ DISSECTOR_ASSERT_NOT_REACHED();
+ ;
+ }
+ return format;
+}
+
static const char*
hfinfo_int64_format(header_field_info *hfinfo)
{
return proto_tree_add_bits_ret_val(tree, hf_index, tvb, bit_offset, no_of_bits, NULL, little_endian);
}
-/*
+/*
* This function will dissect a sequence of bits that does not need to be byte aligned the bits
* set vill be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
* Offset should be given in bits from the start of the tvb.
offset = bit_offset>>3;
- /*
+ /*
* Calculate the number of octets used to hold the bits
*/
tot_no_bits = ((bit_offset&0x7)+no_of_bits);