diff options
author | wmeier <wmeier@f5534014-38df-0310-8fa8-9805f1628bb7> | 2010-10-19 14:31:05 +0000 |
---|---|---|
committer | wmeier <wmeier@f5534014-38df-0310-8fa8-9805f1628bb7> | 2010-10-19 14:31:05 +0000 |
commit | c127b934a0e34c14c01c31afe1cb979326b1d7f3 (patch) | |
tree | cde9a527298be837fb89514f99394e606289ce31 /epan/dissectors | |
parent | b98f23866e762683c9ee636c0d938d1749912506 (diff) |
Use dynamically created value_string_ext to store hash/symbol value_strings;
Also: minor code reformatting and re-arrangement.
git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@34569 f5534014-38df-0310-8fa8-9805f1628bb7
Diffstat (limited to 'epan/dissectors')
-rw-r--r-- | epan/dissectors/packet-etch.c | 305 |
1 files changed, 166 insertions, 139 deletions
diff --git a/epan/dissectors/packet-etch.c b/epan/dissectors/packet-etch.c index 8c68771c92..dffa624a5f 100644 --- a/epan/dissectors/packet-etch.c +++ b/epan/dissectors/packet-etch.c @@ -52,7 +52,6 @@ * maximum numbers for symbols from config files */ #define ETCH_MAX_SYMBOL_LENGTH "256" -#define ETCH_MAX_SYMBOLS 1000 /* * Magic Number for Etch @@ -143,17 +142,15 @@ static int hf_etch_symbol = 0; * internal fields/defines for dissector */ -static const char* gbl_keytab_folder = ""; -static guint gbl_etch_port = 0; -static char* gbl_current_keytab_folder = NULL; -static int gbl_symbols_count = 0; -static value_string* gbl_symbols = NULL; +static const char *gbl_keytab_folder = ""; +static guint gbl_etch_port = 0; +static char *gbl_current_keytab_folder = NULL; static int gbl_pdu_counter; static guint32 gbl_old_frame_num; -static emem_strbuf_t* gbl_symbol_buffer = NULL; -static gboolean gbl_have_symbol = FALSE; +static emem_strbuf_t *gbl_symbol_buffer = NULL; +static gboolean gbl_have_symbol = FALSE; /***************************************************************************/ /* Methods */ @@ -161,14 +158,80 @@ static gboolean gbl_have_symbol = FALSE; /* * forward declared dissector methods */ -static void read_key_value(unsigned int *offset, tvbuff_t * tvb, - proto_tree * etch_tree); -static void read_struct(unsigned int *offset, tvbuff_t * tvb, - proto_tree * etch_tree, int add_type_field); -static int read_value(unsigned int *offset, tvbuff_t * tvb, proto_tree * etch_tree, +static void read_key_value(unsigned int *offset, tvbuff_t *tvb, + proto_tree *etch_tree); +static void read_struct(unsigned int *offset, tvbuff_t *tvb, + proto_tree *etch_tree, int add_type_field); +static int read_value(unsigned int *offset, tvbuff_t *tvb, proto_tree *etch_tree, int asWhat); void proto_reg_handoff_etch(void); +/************************************************************************ + * Symbol value-string functions + * Essentially: Build a value_string_ext at runtime: + * a. Upon startup & whenever symbol folder changed: Read from file(s) + * and add all hash/symbol pairs to a GArray; + * b. When file reads complete, sort the GArray and then create a + * value_string_ext from the array for use by match_strval_ext & friends. + * (Code based upon code in packet-diameter.c) + */ +static GArray *gbl_symbols_array = NULL; +static value_string_ext *gbl_symbols_vs_ext = NULL; + +static void +gbl_symbols_new(void) { + g_assert(gbl_symbols_array == NULL); + gbl_symbols_array = g_array_new(TRUE, TRUE, sizeof(value_string)); +} + +static void +gbl_symbols_free(void) { + g_free(gbl_symbols_vs_ext); + gbl_symbols_vs_ext = NULL; + + if (gbl_symbols_array != NULL) { + value_string *vs_p; + guint i; + vs_p = (value_string *)gbl_symbols_array->data; + for (i=0; i<gbl_symbols_array->len; i++) { + g_free((gchar *)vs_p[i].strptr); + } + g_array_free(gbl_symbols_array, TRUE); + gbl_symbols_array = NULL; + } +} + +static void +gbl_symbols_array_append(int hash, gchar *symbol) { + value_string vs = {hash, symbol}; + g_assert(gbl_symbols_array != NULL); + g_array_append_val(gbl_symbols_array, vs); +} + +static gint +gbl_symbols_compare_vs(gconstpointer a, gconstpointer b) +{ + value_string *vsa = (value_string *)a; + value_string *vsb = (value_string *)b; + + if(vsa->value > vsb->value) + return 1; + if(vsa->value < vsb->value) + return -1; + + return 0; +} + +static void +gbl_symbols_vs_ext_new(void) { + g_assert(gbl_symbols_vs_ext == NULL); + g_assert(gbl_symbols_array != NULL); + g_array_sort(gbl_symbols_array, gbl_symbols_compare_vs); + gbl_symbols_vs_ext = value_string_ext_new((value_string *)gbl_symbols_array->data, + gbl_symbols_array->len+1, + "etch-global-symbols" ); +} + /*********************************************************************************/ /* Aux Functions */ @@ -180,15 +243,12 @@ get_byte_length(guint8 typecode) { switch (typecode) { case ETCH_TC_NULL: - return 0; - break; case ETCH_TC_NONE: - return 0; - break; case ETCH_TC_BOOLEAN_FALSE: - return 0; - break; case ETCH_TC_BOOLEAN_TRUE: + case ETCH_TC_EMPTY_STRING: + case ETCH_TC_MIN_TINY_INT: + case ETCH_TC_MAX_TINY_INT: return 0; break; case ETCH_TC_BYTE: @@ -198,59 +258,25 @@ get_byte_length(guint8 typecode) return 2; break; case ETCH_TC_INT: - return 4; - break; - case ETCH_TC_LONG: - return 8; - break; case ETCH_TC_FLOAT: return 4; break; + case ETCH_TC_LONG: case ETCH_TC_DOUBLE: return 8; break; case ETCH_TC_BYTES: - return -1; - break; case ETCH_TC_ARRAY: - return -1; - break; - case ETCH_TC_EMPTY_STRING: - return 0; - break; case ETCH_TC_STRING: - return -1; - break; case ETCH_TC_STRUCT: - return -1; - break; case ETCH_TC_CUSTOM: - return -1; - break; case ETCH_TC_ANY: return -1; break; - case ETCH_TC_MIN_TINY_INT: - return 0; - break; - case ETCH_TC_MAX_TINY_INT: - return 0; + default: + return 0; break; } - return 0; -} - -/* - * add a etch symbol to our symbol cache - */ -static void -add_symbol(int hash, const gchar *symbol) -{ - if (gbl_symbols_count < ETCH_MAX_SYMBOLS - 1) { - gbl_symbols[gbl_symbols_count].value = hash; - gbl_symbols[gbl_symbols_count].strptr = g_strdup_printf("%." ETCH_MAX_SYMBOL_LENGTH "s", symbol); - gbl_symbols_count++; - } } /* @@ -287,7 +313,8 @@ add_symbols_of_file(const char *filename) /* And read the symbol */ pos = strcspn(line, ","); if ((line[pos] != '\0') && (line[pos+1] !='\0')) /* require at least 1 char in symbol */ - add_symbol(hash, &line[pos+1]); + gbl_symbols_array_append(hash, + g_strdup_printf("%." ETCH_MAX_SYMBOL_LENGTH "s", &line[pos+1])); } fclose(pFile); } @@ -299,30 +326,25 @@ add_symbols_of_file(const char *filename) static void read_hashed_symbols_from_dir(const char *dirname) { - WS_DIR *dir; - WS_DIRENT *file; - const char *name; - char *filename; - GError *err_p = NULL; - int i; + WS_DIR *dir; + WS_DIRENT *file; + const char *name; + char *filename; + GError *err_p = NULL; if(gbl_current_keytab_folder != NULL) { g_free(gbl_current_keytab_folder); gbl_current_keytab_folder = NULL; } - for(i = 0; i < gbl_symbols_count; i++){ - value_string tmp = {0, NULL}; - g_free((gchar *)gbl_symbols[i].strptr); - gbl_symbols[i] = tmp; - } - /* Reset all symbols */ - gbl_symbols_count = 0; + gbl_symbols_free(); if ((dirname == NULL) || (dirname[0] == '\0')) return; if ((dir = ws_dir_open(dirname, 0, &err_p)) != NULL) { + gbl_symbols_new(); + gbl_current_keytab_folder = g_strdup(dirname); while ((file = ws_dir_read_name(dir)) != NULL) { name = ws_dir_get_name(file); @@ -336,6 +358,7 @@ read_hashed_symbols_from_dir(const char *dirname) } } ws_dir_close(dir); + gbl_symbols_vs_ext_new(); }else{ report_failure("%s", err_p->message); g_error_free(err_p); @@ -343,17 +366,17 @@ read_hashed_symbols_from_dir(const char *dirname) } /***********************************************************************************/ -/* Etch Protocol Functions*/ +/* Etch Protocol Functions */ /* * read a type flag from tvb and add it to tree */ static guint8 -read_type(unsigned int *offset, tvbuff_t * tvb, proto_tree * etch_tree) +read_type(unsigned int *offset, tvbuff_t *tvb, proto_tree *etch_tree) { - guint32 type_code; - const gchar* type_as_string; + guint32 type_code; + const gchar *type_as_string; type_code = tvb_get_guint8(tvb, *offset); type_as_string = val_to_str(type_code, tc_lookup_table, "Etch TypeCode: 0x%02x"); @@ -366,14 +389,14 @@ read_type(unsigned int *offset, tvbuff_t * tvb, proto_tree * etch_tree) * read a array type flag and add it to tree */ static void -read_array_type(unsigned int *offset, tvbuff_t * tvb, proto_tree * etch_tree) +read_array_type(unsigned int *offset, tvbuff_t *tvb, proto_tree *etch_tree) { guint32 type_code; type_code = tvb_get_guint8(tvb, *offset); read_type(offset, tvb, etch_tree); - if (type_code == (guint8) ETCH_TC_CUSTOM) { + if (type_code == ETCH_TC_CUSTOM) { type_code = read_type(offset, tvb, etch_tree); proto_tree_add_item(etch_tree, hf_etch_value, tvb, *offset, 4, ENC_BIG_ENDIAN); @@ -386,7 +409,7 @@ read_array_type(unsigned int *offset, tvbuff_t * tvb, proto_tree * etch_tree) * read the length of an array and add it to tree */ static guint32 -read_length(unsigned int *offset, tvbuff_t * tvb, proto_tree * etch_tree) +read_length(unsigned int *offset, tvbuff_t *tvb, proto_tree *etch_tree) { guint32 length; int length_of_array_length_type; @@ -394,7 +417,7 @@ read_length(unsigned int *offset, tvbuff_t * tvb, proto_tree * etch_tree) tiny = tvb_get_guint8(tvb, *offset); - /* Is this the value already?*/ + /* Is this the value already? */ if ( tiny <= ETCH_TC_MAX_TINY_INT || tiny >= ETCH_TC_MIN_TINY_INT) { length = tiny; @@ -406,16 +429,16 @@ read_length(unsigned int *offset, tvbuff_t * tvb, proto_tree * etch_tree) switch (length_of_array_length_type) { case 1: - length = (guint32) tvb_get_guint8(tvb, *offset); + length = tvb_get_guint8(tvb, *offset); break; case 2: - length = (guint32) tvb_get_ntohs(tvb, *offset); + length = tvb_get_ntohs(tvb, *offset); break; case 4: - length = (guint32) tvb_get_ntohl(tvb, *offset); + length = tvb_get_ntohl(tvb, *offset); break; default: - return 0; /* error!*/ + return 0; /* error! */ } } proto_tree_add_item(etch_tree, hf_etch_length, tvb, *offset, @@ -429,27 +452,27 @@ read_length(unsigned int *offset, tvbuff_t * tvb, proto_tree * etch_tree) * read an array from tvb and add it to tree */ static void -read_array(unsigned int *offset, tvbuff_t * tvb, proto_tree * etch_tree) +read_array(unsigned int *offset, tvbuff_t *tvb, proto_tree *etch_tree) { int length; - /* array type*/ + /* array type */ read_type(offset, tvb, etch_tree); - /* Array of type:*/ + /* Array of type: */ read_array_type(offset, tvb, etch_tree); - /* Array dim*/ + /* Array dim */ proto_tree_add_item(etch_tree, hf_etch_dim, tvb, *offset, 1, ENC_NA); (*offset)++; - /* Array length*/ + /* Array length */ length = read_length(offset, tvb, etch_tree); for (; length > 0; length--) { read_value(offset, tvb, etch_tree, hf_etch_value); } - /* terminaton*/ + /* terminaton */ read_type(offset, tvb, etch_tree); } @@ -458,7 +481,7 @@ read_array(unsigned int *offset, tvbuff_t * tvb, proto_tree * etch_tree) * read a sequence of bytes and add them to tree */ static void -read_bytes(unsigned int *offset, tvbuff_t * tvb, proto_tree * etch_tree) +read_bytes(unsigned int *offset, tvbuff_t *tvb, proto_tree *etch_tree) { int length; read_type(offset, tvb, etch_tree); @@ -472,7 +495,7 @@ read_bytes(unsigned int *offset, tvbuff_t * tvb, proto_tree * etch_tree) * read a string and add it to tree */ static void -read_string(unsigned int *offset, tvbuff_t * tvb, proto_tree * etch_tree) +read_string(unsigned int *offset, tvbuff_t *tvb, proto_tree *etch_tree) { int byteLength; read_type(offset, tvb, etch_tree); @@ -488,7 +511,7 @@ read_string(unsigned int *offset, tvbuff_t * tvb, proto_tree * etch_tree) * read a number and add it to tree */ static void -read_number(unsigned int *offset, tvbuff_t * tvb, proto_tree * etch_tree, +read_number(unsigned int *offset, tvbuff_t *tvb, proto_tree *etch_tree, int asWhat, guint8 type_code) { int byteLength; @@ -496,14 +519,14 @@ read_number(unsigned int *offset, tvbuff_t * tvb, proto_tree * etch_tree, read_type(offset, tvb, etch_tree); byteLength = get_byte_length(type_code); if (byteLength > 0) { - proto_item *ti; - const gchar* symbol = NULL; - guint32 hash = 0; + proto_item *ti; + const gchar *symbol = NULL; + guint32 hash = 0; gbl_symbol_buffer = ep_strbuf_new_label(""); /* no symbol found yet */ if (byteLength == 4) { hash = tvb_get_ntohl(tvb, *offset); - symbol = match_strval((const guint32)hash, gbl_symbols); + symbol = match_strval_ext(hash, gbl_symbols_vs_ext); if(symbol != NULL) { asWhat = hf_etch_symbol; gbl_have_symbol = TRUE; @@ -523,7 +546,7 @@ read_number(unsigned int *offset, tvbuff_t * tvb, proto_tree * etch_tree, * read a value and add it to tree */ static int -read_value(unsigned int *offset, tvbuff_t * tvb, proto_tree * etch_tree, +read_value(unsigned int *offset, tvbuff_t *tvb, proto_tree *etch_tree, int asWhat) { guint8 type_code; @@ -535,30 +558,40 @@ read_value(unsigned int *offset, tvbuff_t * tvb, proto_tree * etch_tree, proto_tree_add_item(etch_tree, asWhat, tvb, *offset, 1, ENC_BIG_ENDIAN); (*offset)++; return type_code; - } else if (type_code == ETCH_TC_CUSTOM) { + } + + switch(type_code) { + case ETCH_TC_CUSTOM: read_struct(offset, tvb, etch_tree, 1); - return 0; - } else if (type_code == ETCH_TC_ARRAY) { + break; + case ETCH_TC_ARRAY: read_array(offset, tvb, etch_tree); - return 0; - } else if (type_code == ETCH_TC_STRING) { + break; + case ETCH_TC_STRING: read_string(offset, tvb, etch_tree); - return 0; - } else if (type_code == ETCH_TC_FLOAT) { + break; + case ETCH_TC_FLOAT: read_number(offset, tvb, etch_tree, hf_etch_float, type_code); - } else if (type_code == ETCH_TC_DOUBLE) { + break; + case ETCH_TC_DOUBLE: read_number(offset, tvb, etch_tree, hf_etch_double, type_code); - } else if (type_code == ETCH_TC_SHORT) { + break; + case ETCH_TC_SHORT: read_number(offset, tvb, etch_tree, hf_etch_short, type_code); - } else if (type_code == ETCH_TC_INT) { + break; + case ETCH_TC_INT: read_number(offset, tvb, etch_tree, hf_etch_int, type_code); - } else if (type_code == ETCH_TC_LONG) { + break; + case ETCH_TC_LONG: read_number(offset, tvb, etch_tree, hf_etch_long, type_code); - } else if (type_code == ETCH_TC_BYTE) { + break; + case ETCH_TC_BYTE: read_number(offset, tvb, etch_tree, hf_etch_byte, type_code); - } else if (type_code == ETCH_TC_BYTES) { + break; + case ETCH_TC_BYTES: read_bytes(offset, tvb, etch_tree); - } else { + break; + default: read_number(offset, tvb, etch_tree, asWhat, type_code); } return 0; @@ -568,7 +601,7 @@ read_value(unsigned int *offset, tvbuff_t * tvb, proto_tree * etch_tree, * read a struct and add it to tree */ static void -read_struct(unsigned int *offset, tvbuff_t * tvb, proto_tree * etch_tree, +read_struct(unsigned int *offset, tvbuff_t *tvb, proto_tree *etch_tree, int add_type_field) { proto_item *ti; @@ -583,10 +616,10 @@ read_struct(unsigned int *offset, tvbuff_t * tvb, proto_tree * etch_tree, if (add_type_field) { read_type(offset, tvb, new_tree); } - /* struct type as hash*/ + /* struct type as hash */ read_value(offset, tvb, new_tree, hf_etch_value); - /* struct length */ + /* struct length */ length = read_value(offset, tvb, new_tree, hf_etch_length); for (i = 0; i < length; i++) { @@ -601,7 +634,7 @@ read_struct(unsigned int *offset, tvbuff_t * tvb, proto_tree * etch_tree, * read a key value pair and add it to tree */ static void -read_key_value(unsigned int *offset, tvbuff_t * tvb, proto_tree * etch_tree) +read_key_value(unsigned int *offset, tvbuff_t *tvb, proto_tree *etch_tree) { proto_tree *new_tree; proto_tree *new_tree_bck; @@ -633,17 +666,17 @@ read_key_value(unsigned int *offset, tvbuff_t * tvb, proto_tree * etch_tree) read_value(offset, tvb, new_tree, hf_etch_value); } -/****************************************************************************************************/ +/*************************************************************************/ /* * Preparse the message for the info column */ static emem_strbuf_t* -get_column_info(tvbuff_t * tvb) +get_column_info(tvbuff_t *tvb) { int byte_length; - guint8 type_code; - emem_strbuf_t* result_buf; - int my_offset = 0; + guint8 type_code; + emem_strbuf_t *result_buf; + int my_offset = 0; /* We've a full PDU: 8 bytes + pdu_packetlen bytes */ result_buf = ep_strbuf_new_label(""); @@ -655,10 +688,10 @@ get_column_info(tvbuff_t * tvb) my_offset++; if (byte_length == 4) { - const gchar* symbol; - guint32 hash; + const gchar *symbol; + guint32 hash; hash = tvb_get_ntohl(tvb, my_offset); - symbol = val_to_str((const guint32) hash, gbl_symbols, "%x"); + symbol = match_strval_ext(hash, gbl_symbols_vs_ext); if (symbol != NULL) { ep_strbuf_append_printf(result_buf, "%s()", symbol); } @@ -673,10 +706,10 @@ get_column_info(tvbuff_t * tvb) * main dissector function for an etch message */ static void -dissect_etch_message(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree) +dissect_etch_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { /* We've a full PDU: 8 bytes + pdu_packetlen bytes */ - emem_strbuf_t* colInfo = NULL; + emem_strbuf_t *colInfo = NULL; if (pinfo->cinfo || tree) { colInfo = get_column_info(tvb); /* get current symbol */ @@ -720,7 +753,7 @@ dissect_etch_message(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree) * determine PDU length of protocol etch */ static guint -get_etch_message_len(packet_info * pinfo _U_, tvbuff_t * tvb, int offset) +get_etch_message_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset) { /* length is at offset 4. we add magic bytes length + length size */ return tvb_get_ntohl(tvb, offset + 4) + 8; @@ -731,7 +764,7 @@ get_etch_message_len(packet_info * pinfo _U_, tvbuff_t * tvb, int offset) * main dissector function for the etch protocol */ static int -dissect_etch(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree) +dissect_etch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { if (tvb_length(tvb) < 4) { /* Too small for an etch packet. */ @@ -764,7 +797,6 @@ etch_dissector_init(void) void proto_register_etch(void) { module_t *etch_module; - int i = 0; static hf_register_info hf[] = { {&hf_etch_sig, @@ -793,7 +825,7 @@ void proto_register_etch(void) }, {&hf_etch_typecode, {"Etch TypeCode", "etch.typecode", - FT_STRING, BASE_NONE, /* FT_INT8*/ + FT_STRING, BASE_NONE, /* FT_INT8 */ NULL, 0x0, NULL, HFILL} }, @@ -898,16 +930,9 @@ void proto_register_etch(void) &ett_etch_value, }; - gbl_symbols = (value_string*) g_malloc(ETCH_MAX_SYMBOLS * sizeof(value_string)); - - for(i = 0; i < ETCH_MAX_SYMBOLS; i++){ - value_string tmp = {0, NULL}; - gbl_symbols[i] = tmp; - } - - proto_etch = proto_register_protocol("Apache Etch Protocol", /* name */ - "ETCH", /* short name */ - "etch" /* abbrev */ + proto_etch = proto_register_protocol("Apache Etch Protocol", /* name */ + "ETCH", /* short name */ + "etch" /* abbrev */ ); proto_register_field_array(proto_etch, hf, array_length(hf)); @@ -921,7 +946,9 @@ void proto_register_etch(void) prefs_register_string_preference(etch_module, "file", "Apache Etch symbol folder", - "Place the hash/symbol files (generated by the Apache Etch compiler) ending with .ewh here", + "Place the hash/symbol files " + "(generated by the Apache Etch compiler) " + "ending with .ewh here", &gbl_keytab_folder); prefs_register_uint_preference(etch_module, "tcp.port", "etch TCP Port", |